{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "AE_RL_NSL-KDD.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/gcamfer/Anomaly-ReactionRL/blob/master/Notebooks/AE_RL_NSL_KDD.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "metadata": {
        "id": "e091v728lBCx",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "# AE-RL for NSL-KDD"
      ]
    },
    {
      "metadata": {
        "id": "FEFO4mGvbnlF",
        "colab_type": "code",
        "outputId": "e0e64e06-ea4b-4ebf-826c-c2d3b482c536",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "cell_type": "code",
      "source": [
        "import numpy as np\n",
        "import pandas as pd\n",
        "import matplotlib.pyplot as plt\n",
        "%matplotlib inline\n",
        "from keras.models import Sequential\n",
        "from keras.layers import Dense\n",
        "from keras import optimizers\n",
        "from keras import backend as K\n",
        "import json\n",
        "from sklearn.utils import shuffle\n",
        "import os\n",
        "import sys\n",
        "import time"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Using TensorFlow backend.\n"
          ],
          "name": "stderr"
        }
      ]
    },
    {
      "metadata": {
        "id": "YKA8QTFrb1ZR",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "class data_cls:\n",
        "    def __init__(self,train_test,**kwargs):\n",
        "        col_names = [\"duration\",\"protocol_type\",\"service\",\"flag\",\"src_bytes\",\n",
        "            \"dst_bytes\",\"land_f\",\"wrong_fragment\",\"urgent\",\"hot\",\"num_failed_logins\",\n",
        "            \"logged_in\",\"num_compromised\",\"root_shell\",\"su_attempted\",\"num_root\",\n",
        "            \"num_file_creations\",\"num_shells\",\"num_access_files\",\"num_outbound_cmds\",\n",
        "            \"is_host_login\",\"is_guest_login\",\"count\",\"srv_count\",\"serror_rate\",\n",
        "            \"srv_serror_rate\",\"rerror_rate\",\"srv_rerror_rate\",\"same_srv_rate\",\n",
        "            \"diff_srv_rate\",\"srv_diff_host_rate\",\"dst_host_count\",\"dst_host_srv_count\",\n",
        "            \"dst_host_same_srv_rate\",\"dst_host_diff_srv_rate\",\"dst_host_same_src_port_rate\",\n",
        "            \"dst_host_srv_diff_host_rate\",\"dst_host_serror_rate\",\"dst_host_srv_serror_rate\",\n",
        "            \"dst_host_rerror_rate\",\"dst_host_srv_rerror_rate\",\"labels\",\"dificulty\"]\n",
        "        self.index = 0\n",
        "        # Data formated path and test path. \n",
        "        self.loaded = False\n",
        "        self.train_test = train_test\n",
        "        self.train_path = kwargs.get('train_path', 'datasets/NSL/KDDTrain+.txt')\n",
        "        self.test_path = kwargs.get('test_path',\n",
        "                                    'https://raw.githubusercontent.com/gcamfer/Anomaly-ReactionRL/master/datasets/NSL/KDDTest%2B.txt')\n",
        "        \n",
        "        self.formated_train_path = kwargs.get('formated_train_path', \n",
        "                                              \"formated_train_adv.data\")\n",
        "        self.formated_test_path = kwargs.get('formated_test_path',\n",
        "                                             \"formated_test_adv.data\")\n",
        "        \n",
        "        self.attack_types = ['normal','DoS','Probe','R2L','U2R']\n",
        "        self.attack_names = []\n",
        "        self.attack_map =   { 'normal': 'normal',\n",
        "                        \n",
        "                        'back': 'DoS',\n",
        "                        'land': 'DoS',\n",
        "                        'neptune': 'DoS',\n",
        "                        'pod': 'DoS',\n",
        "                        'smurf': 'DoS',\n",
        "                        'teardrop': 'DoS',\n",
        "                        'mailbomb': 'DoS',\n",
        "                        'apache2': 'DoS',\n",
        "                        'processtable': 'DoS',\n",
        "                        'udpstorm': 'DoS',\n",
        "                        \n",
        "                        'ipsweep': 'Probe',\n",
        "                        'nmap': 'Probe',\n",
        "                        'portsweep': 'Probe',\n",
        "                        'satan': 'Probe',\n",
        "                        'mscan': 'Probe',\n",
        "                        'saint': 'Probe',\n",
        "                    \n",
        "                        'ftp_write': 'R2L',\n",
        "                        'guess_passwd': 'R2L',\n",
        "                        'imap': 'R2L',\n",
        "                        'multihop': 'R2L',\n",
        "                        'phf': 'R2L',\n",
        "                        'spy': 'R2L',\n",
        "                        'warezclient': 'R2L',\n",
        "                        'warezmaster': 'R2L',\n",
        "                        'sendmail': 'R2L',\n",
        "                        'named': 'R2L',\n",
        "                        'snmpgetattack': 'R2L',\n",
        "                        'snmpguess': 'R2L',\n",
        "                        'xlock': 'R2L',\n",
        "                        'xsnoop': 'R2L',\n",
        "                        'worm': 'R2L',\n",
        "                        \n",
        "                        'buffer_overflow': 'U2R',\n",
        "                        'loadmodule': 'U2R',\n",
        "                        'perl': 'U2R',\n",
        "                        'rootkit': 'U2R',\n",
        "                        'httptunnel': 'U2R',\n",
        "                        'ps': 'U2R',    \n",
        "                        'sqlattack': 'U2R',\n",
        "                        'xterm': 'U2R'\n",
        "                    }\n",
        "        self.all_attack_names = list(self.attack_map.keys())\n",
        "\n",
        "        formated = False     \n",
        "        \n",
        "        # Test formated data exists\n",
        "        if os.path.exists(self.formated_train_path) and os.path.exists(self.formated_test_path):\n",
        "            formated = True\n",
        "       \n",
        "        self.formated_dir = \"../datasets/formated/\"\n",
        "        if not os.path.exists(self.formated_dir):\n",
        "            os.makedirs(self.formated_dir)\n",
        "               \n",
        "            \n",
        "        # If it does not exist, it's needed to format the data\n",
        "        if not formated:\n",
        "            ''' Formating the dataset for ready-2-use data'''\n",
        "            self.df = pd.read_csv(self.train_path,sep=',',names=col_names,index_col=False)\n",
        "            if 'dificulty' in self.df.columns:\n",
        "                self.df.drop('dificulty', axis=1, inplace=True) #in case of difficulty     \n",
        "                \n",
        "            data2 = pd.read_csv(self.test_path,sep=',',names=col_names,index_col=False)\n",
        "            if 'dificulty' in data2:\n",
        "                del(data2['dificulty'])\n",
        "            train_indx = self.df.shape[0]\n",
        "            frames = [self.df,data2]\n",
        "            self.df = pd.concat(frames)\n",
        "            \n",
        "            # Dataframe processing\n",
        "            self.df = pd.concat([self.df.drop('protocol_type', axis=1), pd.get_dummies(self.df['protocol_type'])], axis=1)\n",
        "            self.df = pd.concat([self.df.drop('service', axis=1), pd.get_dummies(self.df['service'])], axis=1)\n",
        "            self.df = pd.concat([self.df.drop('flag', axis=1), pd.get_dummies(self.df['flag'])], axis=1)\n",
        "              \n",
        "            # 1 if ``su root'' command attempted; 0 otherwise \n",
        "            self.df['su_attempted'] = self.df['su_attempted'].replace(2.0, 0.0)\n",
        "            \n",
        "             # One hot encoding for labels\n",
        "            self.df = pd.concat([self.df.drop('labels', axis=1),\n",
        "                            pd.get_dummies(self.df['labels'])], axis=1)\n",
        "            \n",
        "            \n",
        "            # Normalization of the df\n",
        "            #normalized_df=(df-df.mean())/df.std()\n",
        "            for indx,dtype in self.df.dtypes.iteritems():\n",
        "                if dtype == 'float64' or dtype == 'int64':\n",
        "                    if self.df[indx].max() == 0 and self.df[indx].min()== 0:\n",
        "                        self.df[indx] = 0\n",
        "                    else:\n",
        "                        self.df[indx] = (self.df[indx]-self.df[indx].min())/(self.df[indx].max()-self.df[indx].min())\n",
        "            \n",
        "            \n",
        "            # Save data\n",
        "            test_df = self.df.iloc[train_indx:self.df.shape[0]]\n",
        "            test_df = shuffle(test_df,random_state=np.random.randint(0,100))\n",
        "            self.df = self.df[:train_indx]\n",
        "            self.df = shuffle(self.df,random_state=np.random.randint(0,100))\n",
        "            test_df.to_csv(self.formated_test_path,sep=',',index=False)\n",
        "            self.df.to_csv(self.formated_train_path,sep=',',index=False)\n",
        "            \n",
        "            # Create a list with the existent attacks in the df\n",
        "            for att in self.attack_map:\n",
        "                if att in self.df.columns:\n",
        "                # Add only if there is exist at least 1\n",
        "                    if np.sum(self.df[att].values) > 1:\n",
        "                        self.attack_names.append(att)\n",
        "\n",
        "    def get_shape(self):\n",
        "        if self.loaded is False:\n",
        "            self._load_df()\n",
        "        \n",
        "        self.data_shape = self.df.shape\n",
        "        # stata + labels\n",
        "        return self.data_shape\n",
        "    \n",
        "    ''' Get n-rows from loaded data \n",
        "        The dataset must be loaded in RAM\n",
        "    '''\n",
        "    def get_batch(self,batch_size=100):\n",
        "        if self.loaded is False:\n",
        "            self._load_df()\n",
        "        \n",
        "        # Read the df rows\n",
        "        indexes = list(range(self.index,self.index+batch_size))    \n",
        "        if max(indexes)>self.data_shape[0]-1:\n",
        "            dif = max(indexes)-self.data_shape[0]\n",
        "            indexes[len(indexes)-dif-1:len(indexes)] = list(range(dif+1))\n",
        "            self.index=batch_size-dif\n",
        "            batch = self.df.iloc[indexes]\n",
        "        else: \n",
        "            batch = self.df.iloc[indexes]\n",
        "            self.index += batch_size    \n",
        "            \n",
        "        labels = batch[self.attack_names]\n",
        "        \n",
        "        batch = batch.drop(self.all_attack_names,axis=1)\n",
        "            \n",
        "        return batch,labels\n",
        "    \n",
        "    def get_full(self):\n",
        "        if self.loaded is False:\n",
        "            self._load_df()\n",
        "            \n",
        "        \n",
        "        labels = self.df[self.attack_names]\n",
        "        \n",
        "        batch = self.df.drop(self.all_attack_names,axis=1)\n",
        "        \n",
        "\n",
        "        return batch,labels\n",
        "      \n",
        "    def _load_df(self):\n",
        "        if self.train_test == 'train':\n",
        "            self.df = pd.read_csv(self.formated_train_path,sep=',') # Read again the csv\n",
        "        else:\n",
        "            self.df = pd.read_csv(self.formated_test_path,sep=',')\n",
        "        self.index=np.random.randint(0,self.df.shape[0]-1,dtype=np.int32)\n",
        "        self.loaded = True\n",
        "         # Create a list with the existent attacks in the df\n",
        "        for att in self.attack_map:\n",
        "            if att in self.df.columns:\n",
        "                # Add only if there is exist at least 1\n",
        "                if np.sum(self.df[att].values) > 1:\n",
        "                    self.attack_names.append(att)\n",
        "        #self.headers = list(self.df)\n",
        " "
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "5DbMxSATehU-",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "# Huber loss function        \n",
        "def huber_loss(y_true, y_pred, clip_value=1):\n",
        "    # Huber loss, see https://en.wikipedia.org/wiki/Huber_loss and\n",
        "    # https://medium.com/@karpathy/yes-you-should-understand-backprop-e2f06eab496b\n",
        "    # for details.\n",
        "    assert clip_value > 0.\n",
        "\n",
        "    x = y_true - y_pred\n",
        "    if np.isinf(clip_value):\n",
        "        # Spacial case for infinity since Tensorflow does have problems\n",
        "        # if we compare `K.abs(x) < np.inf`.\n",
        "        return .5 * K.square(x)\n",
        "\n",
        "    condition = K.abs(x) < clip_value\n",
        "    squared_loss = .5 * K.square(x)\n",
        "    linear_loss = clip_value * (K.abs(x) - .5 * clip_value)\n",
        "    if K.backend() == 'tensorflow':\n",
        "        import tensorflow as tf\n",
        "        if hasattr(tf, 'select'):\n",
        "            return tf.select(condition, squared_loss, linear_loss)  # condition, true, false\n",
        "        else:\n",
        "            return tf.where(condition, squared_loss, linear_loss)  # condition, true, false\n",
        "    elif K.backend() == 'theano':\n",
        "        from theano import tensor as T\n",
        "        return T.switch(condition, squared_loss, linear_loss)\n",
        "    else:\n",
        "        raise RuntimeError('Unknown backend \"{}\".'.format(K.backend()))\n",
        "\n",
        "# Needed for keras huber_loss locate\n",
        "import keras.losses\n",
        "keras.losses.huber_loss = huber_loss\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "7XkKb6WaesLN",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "class QNetwork():\n",
        "    \"\"\"\n",
        "    Q-Network Estimator\n",
        "    Represents the global model for the table\n",
        "    \"\"\"\n",
        "\n",
        "    def __init__(self,obs_size,num_actions,hidden_size = 100,\n",
        "                 hidden_layers = 1,learning_rate=.2):\n",
        "        \"\"\"\n",
        "        Initialize the network with the provided shape\n",
        "        \"\"\"\n",
        "        self.obs_size = obs_size\n",
        "        self.num_actions = num_actions\n",
        "        \n",
        "        # Network arquitecture\n",
        "        self.model = Sequential()\n",
        "        # Add imput layer\n",
        "        self.model.add(Dense(hidden_size, input_shape=(obs_size,),\n",
        "                             activation='relu'))\n",
        "        # Add hidden layers\n",
        "        for layers in range(hidden_layers):\n",
        "            self.model.add(Dense(hidden_size, activation='relu'))\n",
        "        # Add output layer    \n",
        "        self.model.add(Dense(num_actions))\n",
        "        \n",
        "        #optimizer = optimizers.SGD(learning_rate)\n",
        "        # optimizer = optimizers.Adam(alpha=learning_rate)\n",
        "        optimizer = optimizers.Adam(0.00025)\n",
        "        # optimizer = optimizers.RMSpropGraves(learning_rate, 0.95, self.momentum, 1e-2)\n",
        "        \n",
        "        # Compilation of the model with optimizer and loss\n",
        "        self.model.compile(loss=huber_loss,optimizer=optimizer)\n",
        "\n",
        "    def predict(self,state,batch_size=1):\n",
        "        \"\"\"\n",
        "        Predicts action values.\n",
        "        \"\"\"\n",
        "        return self.model.predict(state,batch_size=batch_size)\n",
        "\n",
        "    def update(self, states, q):\n",
        "        \"\"\"\n",
        "        Updates the estimator with the targets.\n",
        "\n",
        "        Args:\n",
        "          states: Target states\n",
        "          q: Estimated values\n",
        "\n",
        "        Returns:\n",
        "          The calculated loss on the batch.\n",
        "        \"\"\"\n",
        "        loss = self.model.train_on_batch(states, q)\n",
        "        return loss\n",
        "    \n",
        "    def copy_model(model):\n",
        "        \"\"\"Returns a copy of a keras model.\"\"\"\n",
        "        model.save('tmp_model')\n",
        "        return keras.models.load_model('tmp_model')\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "-u8-r77Jexf2",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "#Policy interface\n",
        "class Policy:\n",
        "    def __init__(self, num_actions, estimator):\n",
        "        self.num_actions = num_actions\n",
        "        self.estimator = estimator\n",
        "    \n",
        "class Epsilon_greedy(Policy):\n",
        "    def __init__(self,estimator ,num_actions ,epsilon,min_epsilon,decay_rate, epoch_length):\n",
        "        Policy.__init__(self, num_actions, estimator)\n",
        "        self.name = \"Epsilon Greedy\"\n",
        "        \n",
        "        if (epsilon is None or epsilon < 0 or epsilon > 1):\n",
        "            print(\"EpsilonGreedy: Invalid value of epsilon\", flush = True)\n",
        "            sys.exit(0)\n",
        "        self.epsilon = epsilon\n",
        "        self.min_epsilon = min_epsilon\n",
        "        self.actions = list(range(num_actions))\n",
        "        self.step_counter = 0\n",
        "        self.epoch_length = epoch_length\n",
        "        self.decay_rate = decay_rate\n",
        "        \n",
        "        #if epsilon is up 0.1, it will be decayed over time\n",
        "        if self.epsilon > 0.01:\n",
        "            self.epsilon_decay = True\n",
        "        else:\n",
        "            self.epsilon_decay = False\n",
        "    \n",
        "    def get_actions(self,states):\n",
        "        # get next action\n",
        "        if np.random.rand() <= self.epsilon:\n",
        "            actions = np.random.randint(0, self.num_actions,states.shape[0])\n",
        "        else:\n",
        "            self.Q = self.estimator.predict(states,states.shape[0])\n",
        "            actions = []\n",
        "            for row in range(self.Q.shape[0]):\n",
        "                best_actions = np.argwhere(self.Q[row] == np.amax(self.Q[row]))\n",
        "                actions.append(best_actions[np.random.choice(len(best_actions))].item())\n",
        "            \n",
        "        self.step_counter += 1 \n",
        "        # decay epsilon after each epoch\n",
        "        if self.epsilon_decay:\n",
        "            if self.step_counter % self.epoch_length == 0:\n",
        "                self.epsilon = max(self.min_epsilon, self.epsilon * self.decay_rate**self.step_counter)\n",
        "            \n",
        "        return actions"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "2gBTfI8ke08v",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "class ReplayMemory(object):\n",
        "    \"\"\"Implements basic replay memory\"\"\"\n",
        "\n",
        "    def __init__(self, observation_size, max_size):\n",
        "        self.observation_size = observation_size\n",
        "        self.num_observed = 0\n",
        "        self.max_size = max_size\n",
        "        self.samples = {\n",
        "                 'obs'      : np.zeros(self.max_size * 1 * self.observation_size,\n",
        "                                       dtype=np.float32).reshape(self.max_size,self.observation_size),\n",
        "                 'action'   : np.zeros(self.max_size * 1, dtype=np.int16).reshape(self.max_size, 1),\n",
        "                 'reward'   : np.zeros(self.max_size * 1).reshape(self.max_size, 1),\n",
        "                 'terminal' : np.zeros(self.max_size * 1, dtype=np.int16).reshape(self.max_size, 1),\n",
        "               }\n",
        "\n",
        "    def observe(self, state, action, reward, done):\n",
        "        index = self.num_observed % self.max_size\n",
        "        self.samples['obs'][index, :] = state\n",
        "        self.samples['action'][index, :] = action\n",
        "        self.samples['reward'][index, :] = reward\n",
        "        self.samples['terminal'][index, :] = done\n",
        "\n",
        "        self.num_observed += 1\n",
        "\n",
        "    def sample_minibatch(self, minibatch_size):\n",
        "        max_index = min(self.num_observed, self.max_size) - 1\n",
        "        sampled_indices = np.random.randint(max_index, size=minibatch_size)\n",
        "\n",
        "        s      = np.asarray(self.samples['obs'][sampled_indices, :], dtype=np.float32)\n",
        "        s_next = np.asarray(self.samples['obs'][sampled_indices+1, :], dtype=np.float32)\n",
        "\n",
        "        a      = self.samples['action'][sampled_indices].reshape(minibatch_size)\n",
        "        r      = self.samples['reward'][sampled_indices].reshape((minibatch_size, 1))\n",
        "        done   = self.samples['terminal'][sampled_indices].reshape((minibatch_size, 1))\n",
        "\n",
        "        return (s, a, r, s_next, done)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "qXeEzOaIe32m",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "'''\n",
        "Reinforcement learning Agent definition\n",
        "'''\n",
        "\n",
        "class Agent(object):  \n",
        "        \n",
        "    def __init__(self, actions,obs_size, policy=\"EpsilonGreedy\", **kwargs):\n",
        "        self.actions = actions\n",
        "        self.num_actions = len(actions)\n",
        "        self.obs_size = obs_size\n",
        "        \n",
        "        self.epsilon = kwargs.get('epsilon', 1)\n",
        "        self.min_epsilon = kwargs.get('min_epsilon', .1)\n",
        "        self.gamma = kwargs.get('gamma', .001)\n",
        "        self.minibatch_size = kwargs.get('minibatch_size', 2)\n",
        "        self.epoch_length = kwargs.get('epoch_length', 100)\n",
        "        self.decay_rate = kwargs.get('decay_rate',0.99)\n",
        "        self.ExpRep = kwargs.get('ExpRep',True)\n",
        "        if self.ExpRep:\n",
        "            self.memory = ReplayMemory(self.obs_size, kwargs.get('mem_size', 10))\n",
        "        \n",
        "        self.ddqn_time = 100\n",
        "        self.ddqn_update = self.ddqn_time\n",
        "\n",
        "        \n",
        "        self.model_network = QNetwork(self.obs_size, self.num_actions,\n",
        "                                      kwargs.get('hidden_size', 100),\n",
        "                                      kwargs.get('hidden_layers',1),\n",
        "                                      kwargs.get('learning_rate',.2))\n",
        "        self.target_model_network = QNetwork(self.obs_size, self.num_actions,\n",
        "                                      kwargs.get('hidden_size', 100),\n",
        "                                      kwargs.get('hidden_layers',1),\n",
        "                                      kwargs.get('learning_rate',.2))\n",
        "        self.target_model_network.model = QNetwork.copy_model(self.model_network.model)\n",
        "        \n",
        "        if policy == \"EpsilonGreedy\":\n",
        "            self.policy = Epsilon_greedy(self.model_network,len(actions),\n",
        "                                         self.epsilon,self.min_epsilon,\n",
        "                                         self.decay_rate,self.epoch_length)\n",
        "        \n",
        "        \n",
        "    def learn(self, states, actions,next_states, rewards, done):\n",
        "        if self.ExpRep:\n",
        "            self.memory.observe(states, actions, rewards, done)\n",
        "        else:\n",
        "            self.states = states\n",
        "            self.actions = actions\n",
        "            self.next_states = next_states\n",
        "            self.rewards = rewards\n",
        "            self.done = done        \n",
        "    def update_model(self):\n",
        "        if self.ExpRep:\n",
        "            (states, actions, rewards, next_states, done) = self.memory.sample_minibatch(self.minibatch_size)\n",
        "        else:\n",
        "            states = self.states\n",
        "            rewards = self.rewards\n",
        "            next_states = self.next_states\n",
        "            actions = self.actions\n",
        "            done = self.done\n",
        "        \n",
        "        next_actions = []\n",
        "        # Compute Q targets\n",
        "#        Q_prime = self.model_network.predict(next_states,self.minibatch_size)\n",
        "        Q_prime = self.target_model_network.predict(next_states,self.minibatch_size)\n",
        "        # TODO: fix performance in this loop\n",
        "        for row in range(Q_prime.shape[0]):\n",
        "            best_next_actions = np.argwhere(Q_prime[row] == np.amax(Q_prime[row]))\n",
        "            next_actions.append(best_next_actions[np.random.choice(len(best_next_actions))].item())\n",
        "        sx = np.arange(len(next_actions))\n",
        "        # Compute Q(s,a)\n",
        "        Q = self.model_network.predict(states,self.minibatch_size)\n",
        "        # Q-learning update\n",
        "        # target = reward + gamma * max_a'{Q(next_state,next_action))}\n",
        "        targets = rewards.reshape(Q[sx,actions].shape) + \\\n",
        "                  self.gamma * Q[sx,next_actions] * \\\n",
        "                  (1-done.reshape(Q[sx,actions].shape))   \n",
        "        Q[sx,actions] = targets  \n",
        "        \n",
        "        loss = self.model_network.model.train_on_batch(states,Q)#inputs,targets        \n",
        "        \n",
        "        # timer to ddqn update\n",
        "        self.ddqn_update -= 1\n",
        "        if self.ddqn_update == 0:\n",
        "            self.ddqn_update = self.ddqn_time\n",
        "#            self.target_model_network.model = QNetwork.copy_model(self.model_network.model)\n",
        "            self.target_model_network.model.set_weights(self.model_network.model.get_weights()) \n",
        "        \n",
        "        return loss    \n",
        "\n",
        "    def act(self, state,policy):\n",
        "        raise NotImplementedError"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "h-K4eEuDe-QE",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "yzoWE1L8fCKP",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "class DefenderAgent(Agent):      \n",
        "    def __init__(self, actions, obs_size, policy=\"EpsilonGreedy\", **kwargs):\n",
        "        super().__init__(actions,obs_size, policy=\"EpsilonGreedy\", **kwargs)\n",
        "        \n",
        "    def act(self,states):\n",
        "        # Get actions under the policy\n",
        "        actions = self.policy.get_actions(states)\n",
        "        return actions\n",
        "    \n",
        "class AttackAgent(Agent):      \n",
        "    def __init__(self, actions, obs_size, policy=\"EpsilonGreedy\", **kwargs):\n",
        "        super().__init__(actions,obs_size, policy=\"EpsilonGreedy\", **kwargs)\n",
        "        \n",
        "    def act(self,states):\n",
        "        # Get actions under the policy\n",
        "        actions = self.policy.get_actions(states)\n",
        "        return actions"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "ojLCmmE3fCpw",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "'''\n",
        "Reinforcement learning Enviroment Definition\n",
        "'''\n",
        "class RLenv(data_cls):\n",
        "    def __init__(self,train_test,**kwargs):\n",
        "        data_cls.__init__(self,train_test,**kwargs)\n",
        "        data_cls._load_df(self)\n",
        "        self.data_shape = data_cls.get_shape(self)\n",
        "        self.batch_size = kwargs.get('batch_size',1) # experience replay -> batch = 1\n",
        "        self.iterations_episode = kwargs.get('iterations_episode',10)\n",
        "        if self.batch_size=='full':\n",
        "            self.batch_size = int(self.data_shape[0]/iterations_episode)\n",
        "\n",
        "\n",
        "    '''\n",
        "    _update_state: function to update the current state\n",
        "    Returns:\n",
        "        None\n",
        "    Modifies the self parameters involved in the state:\n",
        "        self.state and self.labels\n",
        "    Also modifies the true labels to get learning knowledge\n",
        "    '''\n",
        "    def _update_state(self):        \n",
        "        self.states,self.labels = data_cls.get_batch(self)\n",
        "        \n",
        "        # Update statistics\n",
        "        self.true_labels += np.sum(self.labels).values\n",
        "\n",
        "    '''\n",
        "    Returns:\n",
        "        + Observation of the enviroment\n",
        "    '''\n",
        "    def reset(self):\n",
        "        # Statistics\n",
        "        self.def_true_labels = np.zeros(len(self.attack_types),dtype=int)\n",
        "        self.def_estimated_labels = np.zeros(len(self.attack_types),dtype=int)\n",
        "        self.att_true_labels = np.zeros(len(self.attack_names),dtype=int)\n",
        "        \n",
        "        self.state_numb = 0\n",
        "        \n",
        "        data_cls._load_df(self) # Reload and random index\n",
        "        self.states,self.labels = data_cls.get_batch(self,self.batch_size)\n",
        "        \n",
        "        self.total_reward = 0\n",
        "        self.steps_in_episode = 0\n",
        "        return self.states.values \n",
        "   \n",
        "    '''\n",
        "    Returns:\n",
        "        State: Next state for the game\n",
        "        Reward: Actual reward\n",
        "        done: If the game ends (no end in this case)\n",
        "    \n",
        "    In the adversarial enviroment, it's only needed to return the actual reward\n",
        "    '''    \n",
        "    def act(self,defender_actions,attack_actions):\n",
        "        # Clear previous rewards        \n",
        "        self.att_reward = np.zeros(len(attack_actions))       \n",
        "        self.def_reward = np.zeros(len(defender_actions))\n",
        "        \n",
        "        \n",
        "        attack = [self.attack_types.index(self.attack_map[self.attack_names[att]]) for att in attack_actions]\n",
        "        \n",
        "        self.def_reward = (np.asarray(defender_actions)==np.asarray(attack))*1\n",
        "        self.att_reward = (np.asarray(defender_actions)!=np.asarray(attack))*1\n",
        "\n",
        "         \n",
        "       \n",
        "        self.def_estimated_labels += np.bincount(defender_actions,minlength=len(self.attack_types))\n",
        "        # TODO\n",
        "        # list comprehension\n",
        "        \n",
        "        for act in attack_actions:\n",
        "            self.def_true_labels[self.attack_types.index(self.attack_map[self.attack_names[act]])] += 1\n",
        "        \n",
        "\n",
        "        # Get new state and new true values \n",
        "        attack_actions = attacker_agent.act(self.states)\n",
        "        self.states = env.get_states(attack_actions)\n",
        "        \n",
        "        # Done allways false in this continuous task       \n",
        "        self.done = np.zeros(len(attack_actions),dtype=bool)\n",
        "            \n",
        "        return self.states, self.def_reward,self.att_reward, attack_actions, self.done\n",
        "    \n",
        "    '''\n",
        "    Provide the actual states for the selected attacker actions\n",
        "    Parameters:\n",
        "        self:\n",
        "        attacker_actions: optimum attacks selected by the attacker\n",
        "            it can be one of attack_names list and select random of this\n",
        "    Returns:\n",
        "        State: Actual state for the selected attacks\n",
        "    '''\n",
        "    def get_states(self,attacker_actions):\n",
        "        first = True\n",
        "        for attack in attacker_actions:\n",
        "            if first:\n",
        "                minibatch = (self.df[self.df[self.attack_names[attack]]==1].sample(1))\n",
        "                first = False\n",
        "            else:\n",
        "                minibatch=minibatch.append(self.df[self.df[self.attack_names[attack]]==1].sample(1))\n",
        "        \n",
        "        self.labels = minibatch[self.attack_names]\n",
        "        minibatch.drop(self.all_attack_names,axis=1,inplace=True)\n",
        "        self.states = minibatch\n",
        "        \n",
        "        return self.states\n",
        "\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "M0eU7ZSGfNEB",
        "colab_type": "code",
        "outputId": "580bd4d2-c5c2-4789-fb1f-95aa23819ce8",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 8568
        }
      },
      "cell_type": "code",
      "source": [
        "if __name__ == \"__main__\":\n",
        "  \n",
        "    kdd_train = \"https://raw.githubusercontent.com/gcamfer/Anomaly-ReactionRL/master/datasets/NSL/KDDTrain%2B.txt\"\n",
        "    kdd_test = \"https://raw.githubusercontent.com/gcamfer/Anomaly-ReactionRL/master/datasets/NSL/KDDTest%2B.txt\"\n",
        "\n",
        "    formated_train_path = \"formated_train_adv.data\"\n",
        "    formated_test_path = \"formated_test_adv.data\"\n",
        "    \n",
        "    \n",
        "    # Train batch\n",
        "    batch_size = 1\n",
        "    # batch of memory ExpRep\n",
        "    minibatch_size = 100\n",
        "    ExpRep = True\n",
        "    \n",
        "    iterations_episode = 100\n",
        "  \n",
        "    # Initialization of the enviroment\n",
        "    env = RLenv('train',train_path=kdd_train,test_path=kdd_test,\n",
        "                formated_train_path = formated_train_path,\n",
        "                formated_test_path = formated_test_path,batch_size=batch_size,\n",
        "                iterations_episode=iterations_episode)    \n",
        "    # obs_size = size of the state\n",
        "    obs_size = env.data_shape[1]-len(env.all_attack_names)\n",
        "    \n",
        "    #num_episodes = int(env.data_shape[0]/(iterations_episode)/10)\n",
        "    num_episodes = 100\n",
        "    \n",
        "    '''\n",
        "    Definition for the defensor agent.\n",
        "    '''\n",
        "    defender_valid_actions = list(range(len(env.attack_types))) # only detect type of attack\n",
        "    defender_num_actions = len(defender_valid_actions)    \n",
        "    \n",
        "\t\n",
        "    def_epsilon = 1 # exploration\n",
        "    min_epsilon = 0.01 # min value for exploration\n",
        "    def_gamma = 0.001\n",
        "    def_decay_rate = 0.99\n",
        "    \n",
        "    def_hidden_size = 100\n",
        "    def_hidden_layers = 3\n",
        "    \n",
        "    def_learning_rate = .2\n",
        "    \n",
        "    defender_agent = DefenderAgent(defender_valid_actions,obs_size,\"EpsilonGreedy\",\n",
        "                          epoch_length = iterations_episode,\n",
        "                          epsilon = def_epsilon,\n",
        "                          min_epsilon = min_epsilon,\n",
        "                          decay_rate = def_decay_rate,\n",
        "                          gamma = def_gamma,\n",
        "                          hidden_size=def_hidden_size,\n",
        "                          hidden_layers=def_hidden_layers,\n",
        "                          minibatch_size = minibatch_size,\n",
        "                          mem_size = 1000,\n",
        "                          learning_rate=def_learning_rate,\n",
        "                          ExpRep=ExpRep)\n",
        "    #Pretrained defender\n",
        "    #defender_agent.model_network.model.load_weights(\"models/type_model.h5\")    \n",
        "    \n",
        "    '''\n",
        "    Definition for the attacker agent.\n",
        "    In this case the exploration is better to be greater\n",
        "    The correlation sould be greater too so gamma bigger\n",
        "    '''\n",
        "    attack_valid_actions = list(range(len(env.attack_names)))\n",
        "    attack_num_actions = len(attack_valid_actions)\n",
        "\t\n",
        "    att_epsilon = 1\n",
        "    min_epsilon = 0.82 # min value for exploration\n",
        "\n",
        "    att_gamma = 0.001\n",
        "    att_decay_rate = 0.99\n",
        "    \n",
        "    att_hidden_layers = 1\n",
        "    att_hidden_size = 100\n",
        "    \n",
        "    att_learning_rate = 0.2\n",
        "    \n",
        "    attacker_agent = AttackAgent(attack_valid_actions,obs_size,\"EpsilonGreedy\",\n",
        "                          epoch_length = iterations_episode,\n",
        "                          epsilon = att_epsilon,\n",
        "                          min_epsilon = min_epsilon,\n",
        "                          decay_rate = att_decay_rate,\n",
        "                          gamma = att_gamma,\n",
        "                          hidden_size=att_hidden_size,\n",
        "                          hidden_layers=att_hidden_layers,\n",
        "                          minibatch_size = minibatch_size,\n",
        "                          mem_size = 1000,\n",
        "                          learning_rate=att_learning_rate,\n",
        "                          ExpRep=ExpRep)\n",
        "    \n",
        "        \n",
        "    \n",
        "    # Statistics\n",
        "    att_reward_chain = []\n",
        "    def_reward_chain = []\n",
        "    att_loss_chain = []\n",
        "    def_loss_chain = []\n",
        "    def_total_reward_chain = []\n",
        "    att_total_reward_chain = []\n",
        "    \n",
        "\t# Print parameters\n",
        "    print(\"-------------------------------------------------------------------------------\")\n",
        "    print(\"Total epoch: {} | Iterations in epoch: {}\"\n",
        "          \"| Minibatch from mem size: {} | Total Samples: {}|\".format(num_episodes,\n",
        "                         iterations_episode,minibatch_size,\n",
        "                         num_episodes*iterations_episode))\n",
        "    print(\"-------------------------------------------------------------------------------\")\n",
        "    print(\"Dataset shape: {}\".format(env.data_shape))\n",
        "    print(\"-------------------------------------------------------------------------------\")\n",
        "    print(\"Attacker parameters: Num_actions={} | gamma={} |\" \n",
        "          \" epsilon={} | ANN hidden size={} | \"\n",
        "          \"ANN hidden layers={}|\".format(attack_num_actions,\n",
        "                             att_gamma,att_epsilon, att_hidden_size,\n",
        "                             att_hidden_layers))\n",
        "    print(\"-------------------------------------------------------------------------------\")\n",
        "    print(\"Defense parameters: Num_actions={} | gamma={} | \"\n",
        "          \"epsilon={} | ANN hidden size={} |\"\n",
        "          \" ANN hidden layers={}|\".format(defender_num_actions,\n",
        "                              def_gamma,def_epsilon,def_hidden_size,\n",
        "                              def_hidden_layers))\n",
        "    print(\"-------------------------------------------------------------------------------\")\n",
        "\n",
        "    # Main loop\n",
        "    attacks_by_epoch = []\n",
        "    attack_labels_list = []\n",
        "    for epoch in range(num_episodes):\n",
        "        start_time = time.time()\n",
        "        att_loss = 0.\n",
        "        def_loss = 0.\n",
        "        def_total_reward_by_episode = 0\n",
        "        att_total_reward_by_episode = 0\n",
        "        # Reset enviromet, actualize the data batch with random state/attacks\n",
        "        states = env.reset()\n",
        "        \n",
        "        # Get actions for actual states following the policy\n",
        "        attack_actions = attacker_agent.act(states)\n",
        "        states = env.get_states(attack_actions)    \n",
        "        \n",
        "        done = False\n",
        "       \n",
        "        attacks_list = []\n",
        "        # Iteration in one episode\n",
        "        for i_iteration in range(iterations_episode):\n",
        "            \n",
        "            attacks_list.append(attack_actions[0])\n",
        "            # apply actions, get rewards and new state\n",
        "            act_time = time.time()  \n",
        "            defender_actions = defender_agent.act(states)\n",
        "            #Enviroment actuation for this actions\n",
        "            next_states,def_reward, att_reward,next_attack_actions, done = env.act(defender_actions,attack_actions)\n",
        "            # If the epoch*batch_size*iterations_episode is largest than the df\n",
        "\n",
        "            \n",
        "            attacker_agent.learn(states,attack_actions,next_states,att_reward,done)\n",
        "            defender_agent.learn(states,defender_actions,next_states,def_reward,done)\n",
        "            \n",
        "            act_end_time = time.time()\n",
        "            \n",
        "            # Train network, update loss after at least minibatch_learns\n",
        "            if ExpRep and epoch*iterations_episode + i_iteration >= minibatch_size:\n",
        "                def_loss += defender_agent.update_model()\n",
        "                att_loss += attacker_agent.update_model()\n",
        "            elif not ExpRep:\n",
        "                def_loss += defender_agent.update_model()\n",
        "                att_loss += attacker_agent.update_model()\n",
        "                \n",
        "\n",
        "            update_end_time = time.time()\n",
        "\n",
        "            # Update the state\n",
        "            states = next_states\n",
        "            attack_actions = next_attack_actions\n",
        "            \n",
        "            \n",
        "            # Update statistics\n",
        "            def_total_reward_by_episode += np.sum(def_reward,dtype=np.int32)\n",
        "            att_total_reward_by_episode += np.sum(att_reward,dtype=np.int32)\n",
        "        \n",
        "        attacks_by_epoch.append(attacks_list)\n",
        "        # Update user view\n",
        "        def_reward_chain.append(def_total_reward_by_episode) \n",
        "        att_reward_chain.append(att_total_reward_by_episode) \n",
        "        def_loss_chain.append(def_loss)\n",
        "        att_loss_chain.append(att_loss) \n",
        "\n",
        "        \n",
        "        end_time = time.time()\n",
        "        print(\"\\r\\n|Epoch {:03d}/{:03d}| time: {:2.2f}|\\r\\n\"\n",
        "                \"|Def Loss {:4.4f} | Def Reward in ep {:03d}|\\r\\n\"\n",
        "                \"|Att Loss {:4.4f} | Att Reward in ep {:03d}|\"\n",
        "                .format(epoch, num_episodes,(end_time-start_time), \n",
        "                def_loss, def_total_reward_by_episode,\n",
        "                att_loss, att_total_reward_by_episode))\n",
        "        \n",
        "        \n",
        "        print(\"|Def Estimated: {}| Att Labels: {}\".format(env.def_estimated_labels,\n",
        "              env.def_true_labels))\n",
        "        attack_labels_list.append(env.def_true_labels)"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "-------------------------------------------------------------------------------\n",
            "Total epoch: 100 | Iterations in epoch: 100| Minibatch from mem size: 100 | Total Samples: 10000|\n",
            "-------------------------------------------------------------------------------\n",
            "Dataset shape: (125973, 162)\n",
            "-------------------------------------------------------------------------------\n",
            "Attacker parameters: Num_actions=23 | gamma=0.001 | epsilon=1 | ANN hidden size=100 | ANN hidden layers=1|\n",
            "-------------------------------------------------------------------------------\n",
            "Defense parameters: Num_actions=5 | gamma=0.001 | epsilon=1 | ANN hidden size=100 | ANN hidden layers=3|\n",
            "-------------------------------------------------------------------------------\n",
            "\n",
            "|Epoch 000/100| time: 3.21|\n",
            "|Def Loss 0.0000 | Def Reward in ep 020|\n",
            "|Att Loss 0.0000 | Att Reward in ep 080|\n",
            "|Def Estimated: [21 18 23 17 21]| Att Labels: [ 3 26 15 41 15]\n",
            "\n",
            "|Epoch 001/100| time: 7.66|\n",
            "|Def Loss 1.0307 | Def Reward in ep 033|\n",
            "|Att Loss 0.9622 | Att Reward in ep 067|\n",
            "|Def Estimated: [ 6 13 12 58 11]| Att Labels: [ 6 25 27 24 18]\n",
            "\n",
            "|Epoch 002/100| time: 5.30|\n",
            "|Def Loss 0.3020 | Def Reward in ep 073|\n",
            "|Att Loss 0.4335 | Att Reward in ep 027|\n",
            "|Def Estimated: [ 6 30 25 23 16]| Att Labels: [ 2 35 18 26 19]\n",
            "\n",
            "|Epoch 003/100| time: 5.61|\n",
            "|Def Loss 0.2317 | Def Reward in ep 084|\n",
            "|Att Loss 0.4418 | Att Reward in ep 016|\n",
            "|Def Estimated: [ 5 36 22 28  9]| Att Labels: [ 5 37 21 28  9]\n",
            "\n",
            "|Epoch 004/100| time: 5.83|\n",
            "|Def Loss 0.2092 | Def Reward in ep 094|\n",
            "|Att Loss 0.4276 | Att Reward in ep 006|\n",
            "|Def Estimated: [ 5 32 16 30 17]| Att Labels: [ 8 30 16 28 18]\n",
            "\n",
            "|Epoch 005/100| time: 5.67|\n",
            "|Def Loss 0.1771 | Def Reward in ep 094|\n",
            "|Att Loss 0.3930 | Att Reward in ep 006|\n",
            "|Def Estimated: [ 8 28 19 31 14]| Att Labels: [ 9 28 18 33 12]\n",
            "\n",
            "|Epoch 006/100| time: 5.87|\n",
            "|Def Loss 0.1437 | Def Reward in ep 091|\n",
            "|Att Loss 0.3616 | Att Reward in ep 009|\n",
            "|Def Estimated: [13 22 19 26 20]| Att Labels: [12 22 19 29 18]\n",
            "\n",
            "|Epoch 007/100| time: 5.61|\n",
            "|Def Loss 0.1614 | Def Reward in ep 091|\n",
            "|Att Loss 0.3506 | Att Reward in ep 009|\n",
            "|Def Estimated: [ 8 25 17 23 27]| Att Labels: [ 8 25 15 23 29]\n",
            "\n",
            "|Epoch 008/100| time: 5.56|\n",
            "|Def Loss 0.1575 | Def Reward in ep 092|\n",
            "|Att Loss 0.3366 | Att Reward in ep 008|\n",
            "|Def Estimated: [ 8 22 18 28 24]| Att Labels: [10 21 19 29 21]\n",
            "\n",
            "|Epoch 009/100| time: 6.00|\n",
            "|Def Loss 0.1360 | Def Reward in ep 091|\n",
            "|Att Loss 0.3072 | Att Reward in ep 009|\n",
            "|Def Estimated: [ 6 32 19 30 13]| Att Labels: [10 30 20 27 13]\n",
            "\n",
            "|Epoch 010/100| time: 5.75|\n",
            "|Def Loss 0.1310 | Def Reward in ep 093|\n",
            "|Att Loss 0.2604 | Att Reward in ep 007|\n",
            "|Def Estimated: [12 23 13 33 19]| Att Labels: [ 9 24 14 32 21]\n",
            "\n",
            "|Epoch 011/100| time: 5.31|\n",
            "|Def Loss 0.1300 | Def Reward in ep 096|\n",
            "|Att Loss 0.1774 | Att Reward in ep 004|\n",
            "|Def Estimated: [ 3 28 22 28 19]| Att Labels: [ 3 29 22 29 17]\n",
            "\n",
            "|Epoch 012/100| time: 6.46|\n",
            "|Def Loss 0.1339 | Def Reward in ep 096|\n",
            "|Att Loss 0.1031 | Att Reward in ep 004|\n",
            "|Def Estimated: [20 24 19 19 18]| Att Labels: [20 24 20 20 16]\n",
            "\n",
            "|Epoch 013/100| time: 6.13|\n",
            "|Def Loss 0.1148 | Def Reward in ep 095|\n",
            "|Att Loss 0.0770 | Att Reward in ep 005|\n",
            "|Def Estimated: [13 21 19 31 16]| Att Labels: [17 19 20 30 14]\n",
            "\n",
            "|Epoch 014/100| time: 6.14|\n",
            "|Def Loss 0.1240 | Def Reward in ep 093|\n",
            "|Att Loss 0.0669 | Att Reward in ep 007|\n",
            "|Def Estimated: [12 23 16 31 18]| Att Labels: [17 21 16 30 16]\n",
            "\n",
            "|Epoch 015/100| time: 6.51|\n",
            "|Def Loss 0.1058 | Def Reward in ep 092|\n",
            "|Att Loss 0.0659 | Att Reward in ep 008|\n",
            "|Def Estimated: [21 24 11 31 13]| Att Labels: [26 21 11 31 11]\n",
            "\n",
            "|Epoch 016/100| time: 5.90|\n",
            "|Def Loss 0.1369 | Def Reward in ep 093|\n",
            "|Att Loss 0.0717 | Att Reward in ep 007|\n",
            "|Def Estimated: [13 22 14 30 21]| Att Labels: [15 21 15 31 18]\n",
            "\n",
            "|Epoch 017/100| time: 5.96|\n",
            "|Def Loss 0.1130 | Def Reward in ep 095|\n",
            "|Att Loss 0.0678 | Att Reward in ep 005|\n",
            "|Def Estimated: [12 19 21 29 19]| Att Labels: [11 19 22 31 17]\n",
            "\n",
            "|Epoch 018/100| time: 6.09|\n",
            "|Def Loss 0.1407 | Def Reward in ep 094|\n",
            "|Att Loss 0.0550 | Att Reward in ep 006|\n",
            "|Def Estimated: [18 24 16 30 12]| Att Labels: [16 25 17 30 12]\n",
            "\n",
            "|Epoch 019/100| time: 5.60|\n",
            "|Def Loss 0.1051 | Def Reward in ep 097|\n",
            "|Att Loss 0.0475 | Att Reward in ep 003|\n",
            "|Def Estimated: [13 20 21 32 14]| Att Labels: [12 20 21 33 14]\n",
            "\n",
            "|Epoch 020/100| time: 6.16|\n",
            "|Def Loss 0.1206 | Def Reward in ep 094|\n",
            "|Att Loss 0.0406 | Att Reward in ep 006|\n",
            "|Def Estimated: [11 23 23 27 16]| Att Labels: [13 21 23 28 15]\n",
            "\n",
            "|Epoch 021/100| time: 5.80|\n",
            "|Def Loss 0.1254 | Def Reward in ep 092|\n",
            "|Att Loss 0.0382 | Att Reward in ep 008|\n",
            "|Def Estimated: [15 21 17 31 16]| Att Labels: [16 20 19 30 15]\n",
            "\n",
            "|Epoch 022/100| time: 6.33|\n",
            "|Def Loss 0.1358 | Def Reward in ep 095|\n",
            "|Att Loss 0.0359 | Att Reward in ep 005|\n",
            "|Def Estimated: [13 27 18 32 10]| Att Labels: [15 28 17 31  9]\n",
            "\n",
            "|Epoch 023/100| time: 5.92|\n",
            "|Def Loss 0.1144 | Def Reward in ep 093|\n",
            "|Att Loss 0.0376 | Att Reward in ep 007|\n",
            "|Def Estimated: [12 25 20 30 13]| Att Labels: [13 24 19 29 15]\n",
            "\n",
            "|Epoch 024/100| time: 6.13|\n",
            "|Def Loss 0.1014 | Def Reward in ep 096|\n",
            "|Att Loss 0.0341 | Att Reward in ep 004|\n",
            "|Def Estimated: [17 19 19 36  9]| Att Labels: [19 18 19 37  7]\n",
            "\n",
            "|Epoch 025/100| time: 5.83|\n",
            "|Def Loss 0.0739 | Def Reward in ep 099|\n",
            "|Att Loss 0.0355 | Att Reward in ep 001|\n",
            "|Def Estimated: [12 27 18 25 18]| Att Labels: [11 27 19 25 18]\n",
            "\n",
            "|Epoch 026/100| time: 6.17|\n",
            "|Def Loss 0.0655 | Def Reward in ep 095|\n",
            "|Att Loss 0.0367 | Att Reward in ep 005|\n",
            "|Def Estimated: [18 20 15 36 11]| Att Labels: [20 21 13 34 12]\n",
            "\n",
            "|Epoch 027/100| time: 5.84|\n",
            "|Def Loss 0.0734 | Def Reward in ep 091|\n",
            "|Att Loss 0.0486 | Att Reward in ep 009|\n",
            "|Def Estimated: [10 20 19 34 17]| Att Labels: [10 21 17 34 18]\n",
            "\n",
            "|Epoch 028/100| time: 6.31|\n",
            "|Def Loss 0.0747 | Def Reward in ep 094|\n",
            "|Att Loss 0.0468 | Att Reward in ep 006|\n",
            "|Def Estimated: [16 26 21 26 11]| Att Labels: [19 26 18 25 12]\n",
            "\n",
            "|Epoch 029/100| time: 5.86|\n",
            "|Def Loss 0.0848 | Def Reward in ep 094|\n",
            "|Att Loss 0.0513 | Att Reward in ep 006|\n",
            "|Def Estimated: [15 18 17 30 20]| Att Labels: [18 17 15 32 18]\n",
            "\n",
            "|Epoch 030/100| time: 6.55|\n",
            "|Def Loss 0.0602 | Def Reward in ep 094|\n",
            "|Att Loss 0.0599 | Att Reward in ep 006|\n",
            "|Def Estimated: [22 16 15 35 12]| Att Labels: [25 14 16 33 12]\n",
            "\n",
            "|Epoch 031/100| time: 6.00|\n",
            "|Def Loss 0.0576 | Def Reward in ep 096|\n",
            "|Att Loss 0.0559 | Att Reward in ep 004|\n",
            "|Def Estimated: [14 32 16 24 14]| Att Labels: [13 33 17 23 14]\n",
            "\n",
            "|Epoch 032/100| time: 5.94|\n",
            "|Def Loss 0.0666 | Def Reward in ep 096|\n",
            "|Att Loss 0.0503 | Att Reward in ep 004|\n",
            "|Def Estimated: [14 21 17 36 12]| Att Labels: [14 22 17 35 12]\n",
            "\n",
            "|Epoch 033/100| time: 6.10|\n",
            "|Def Loss 0.0853 | Def Reward in ep 095|\n",
            "|Att Loss 0.0489 | Att Reward in ep 005|\n",
            "|Def Estimated: [13 28 11 29 19]| Att Labels: [14 27 13 26 20]\n",
            "\n",
            "|Epoch 034/100| time: 6.05|\n",
            "|Def Loss 0.0960 | Def Reward in ep 095|\n",
            "|Att Loss 0.0434 | Att Reward in ep 005|\n",
            "|Def Estimated: [14 23 17 28 18]| Att Labels: [16 22 16 25 21]\n",
            "\n",
            "|Epoch 035/100| time: 6.50|\n",
            "|Def Loss 0.1149 | Def Reward in ep 096|\n",
            "|Att Loss 0.0428 | Att Reward in ep 004|\n",
            "|Def Estimated: [15 23 10 28 24]| Att Labels: [19 21 10 26 24]\n",
            "\n",
            "|Epoch 036/100| time: 6.08|\n",
            "|Def Loss 0.1093 | Def Reward in ep 096|\n",
            "|Att Loss 0.0427 | Att Reward in ep 004|\n",
            "|Def Estimated: [16 18 19 32 15]| Att Labels: [18 18 19 32 13]\n",
            "\n",
            "|Epoch 037/100| time: 5.67|\n",
            "|Def Loss 0.1223 | Def Reward in ep 095|\n",
            "|Att Loss 0.0371 | Att Reward in ep 005|\n",
            "|Def Estimated: [ 9 16 22 37 16]| Att Labels: [ 8 16 22 36 18]\n",
            "\n",
            "|Epoch 038/100| time: 5.85|\n",
            "|Def Loss 0.1043 | Def Reward in ep 099|\n",
            "|Att Loss 0.0310 | Att Reward in ep 001|\n",
            "|Def Estimated: [11 23 16 33 17]| Att Labels: [11 22 17 33 17]\n",
            "\n",
            "|Epoch 039/100| time: 5.70|\n",
            "|Def Loss 0.0963 | Def Reward in ep 094|\n",
            "|Att Loss 0.0326 | Att Reward in ep 006|\n",
            "|Def Estimated: [ 9 26 21 30 14]| Att Labels: [ 9 26 21 30 14]\n",
            "\n",
            "|Epoch 040/100| time: 6.10|\n",
            "|Def Loss 0.1141 | Def Reward in ep 097|\n",
            "|Att Loss 0.0287 | Att Reward in ep 003|\n",
            "|Def Estimated: [14 22 15 30 19]| Att Labels: [17 20 15 30 18]\n",
            "\n",
            "|Epoch 041/100| time: 6.12|\n",
            "|Def Loss 0.0978 | Def Reward in ep 097|\n",
            "|Att Loss 0.0245 | Att Reward in ep 003|\n",
            "|Def Estimated: [15 18 17 21 29]| Att Labels: [17 18 17 21 27]\n",
            "\n",
            "|Epoch 042/100| time: 5.90|\n",
            "|Def Loss 0.1089 | Def Reward in ep 095|\n",
            "|Att Loss 0.0208 | Att Reward in ep 005|\n",
            "|Def Estimated: [18 19 16 36 11]| Att Labels: [15 20 16 36 13]\n",
            "\n",
            "|Epoch 043/100| time: 6.47|\n",
            "|Def Loss 0.1134 | Def Reward in ep 095|\n",
            "|Att Loss 0.0256 | Att Reward in ep 005|\n",
            "|Def Estimated: [21 20 18 28 13]| Att Labels: [21 20 19 26 14]\n",
            "\n",
            "|Epoch 044/100| time: 5.74|\n",
            "|Def Loss 0.0941 | Def Reward in ep 096|\n",
            "|Att Loss 0.0200 | Att Reward in ep 004|\n",
            "|Def Estimated: [14 20 13 34 19]| Att Labels: [13 20 14 32 21]\n",
            "\n",
            "|Epoch 045/100| time: 6.05|\n",
            "|Def Loss 0.0775 | Def Reward in ep 097|\n",
            "|Att Loss 0.0291 | Att Reward in ep 003|\n",
            "|Def Estimated: [10 25 18 30 17]| Att Labels: [13 25 17 29 16]\n",
            "\n",
            "|Epoch 046/100| time: 5.93|\n",
            "|Def Loss 0.0804 | Def Reward in ep 096|\n",
            "|Att Loss 0.0321 | Att Reward in ep 004|\n",
            "|Def Estimated: [11 23 19 30 17]| Att Labels: [13 23 17 30 17]\n",
            "\n",
            "|Epoch 047/100| time: 5.43|\n",
            "|Def Loss 0.0805 | Def Reward in ep 098|\n",
            "|Att Loss 0.0339 | Att Reward in ep 002|\n",
            "|Def Estimated: [ 7 16 21 34 22]| Att Labels: [ 8 15 21 33 23]\n",
            "\n",
            "|Epoch 048/100| time: 6.04|\n",
            "|Def Loss 0.0857 | Def Reward in ep 094|\n",
            "|Att Loss 0.0303 | Att Reward in ep 006|\n",
            "|Def Estimated: [12 22 15 34 17]| Att Labels: [13 20 16 32 19]\n",
            "\n",
            "|Epoch 049/100| time: 5.87|\n",
            "|Def Loss 0.0945 | Def Reward in ep 093|\n",
            "|Att Loss 0.0412 | Att Reward in ep 007|\n",
            "|Def Estimated: [ 6 31 20 19 24]| Att Labels: [ 7 29 20 19 25]\n",
            "\n",
            "|Epoch 050/100| time: 5.64|\n",
            "|Def Loss 0.0969 | Def Reward in ep 097|\n",
            "|Att Loss 0.0358 | Att Reward in ep 003|\n",
            "|Def Estimated: [11 24 19 31 15]| Att Labels: [12 23 20 30 15]\n",
            "\n",
            "|Epoch 051/100| time: 6.35|\n",
            "|Def Loss 0.0963 | Def Reward in ep 098|\n",
            "|Att Loss 0.0364 | Att Reward in ep 002|\n",
            "|Def Estimated: [17 20 18 23 22]| Att Labels: [18 20 18 22 22]\n",
            "\n",
            "|Epoch 052/100| time: 5.97|\n",
            "|Def Loss 0.0904 | Def Reward in ep 097|\n",
            "|Att Loss 0.0354 | Att Reward in ep 003|\n",
            "|Def Estimated: [11 22 14 33 20]| Att Labels: [10 21 16 33 20]\n",
            "\n",
            "|Epoch 053/100| time: 6.02|\n",
            "|Def Loss 0.0651 | Def Reward in ep 096|\n",
            "|Att Loss 0.0337 | Att Reward in ep 004|\n",
            "|Def Estimated: [10 23 22 24 21]| Att Labels: [12 23 19 26 20]\n",
            "\n",
            "|Epoch 054/100| time: 6.26|\n",
            "|Def Loss 0.0683 | Def Reward in ep 097|\n",
            "|Att Loss 0.0330 | Att Reward in ep 003|\n",
            "|Def Estimated: [13 24 15 28 20]| Att Labels: [15 24 15 25 21]\n",
            "\n",
            "|Epoch 055/100| time: 5.82|\n",
            "|Def Loss 0.0607 | Def Reward in ep 100|\n",
            "|Att Loss 0.0302 | Att Reward in ep 000|\n",
            "|Def Estimated: [ 7 23 24 32 14]| Att Labels: [ 7 23 24 32 14]\n",
            "\n",
            "|Epoch 056/100| time: 6.03|\n",
            "|Def Loss 0.0636 | Def Reward in ep 095|\n",
            "|Att Loss 0.0282 | Att Reward in ep 005|\n",
            "|Def Estimated: [10 22 24 22 22]| Att Labels: [ 8 25 23 22 22]\n",
            "\n",
            "|Epoch 057/100| time: 6.20|\n",
            "|Def Loss 0.0554 | Def Reward in ep 097|\n",
            "|Att Loss 0.0305 | Att Reward in ep 003|\n",
            "|Def Estimated: [15 26 20 22 17]| Att Labels: [16 24 20 24 16]\n",
            "\n",
            "|Epoch 058/100| time: 6.14|\n",
            "|Def Loss 0.0560 | Def Reward in ep 095|\n",
            "|Att Loss 0.0325 | Att Reward in ep 005|\n",
            "|Def Estimated: [14 20 19 37 10]| Att Labels: [13 20 20 38  9]\n",
            "\n",
            "|Epoch 059/100| time: 5.98|\n",
            "|Def Loss 0.0520 | Def Reward in ep 091|\n",
            "|Att Loss 0.0286 | Att Reward in ep 009|\n",
            "|Def Estimated: [15 20 16 31 18]| Att Labels: [11 18 17 31 23]\n",
            "\n",
            "|Epoch 060/100| time: 5.77|\n",
            "|Def Loss 0.0453 | Def Reward in ep 097|\n",
            "|Att Loss 0.0316 | Att Reward in ep 003|\n",
            "|Def Estimated: [13 19 24 21 23]| Att Labels: [14 19 24 21 22]\n",
            "\n",
            "|Epoch 061/100| time: 5.89|\n",
            "|Def Loss 0.0312 | Def Reward in ep 098|\n",
            "|Att Loss 0.0292 | Att Reward in ep 002|\n",
            "|Def Estimated: [10 21 26 28 15]| Att Labels: [10 21 25 27 17]\n",
            "\n",
            "|Epoch 062/100| time: 6.26|\n",
            "|Def Loss 0.0396 | Def Reward in ep 099|\n",
            "|Att Loss 0.0294 | Att Reward in ep 001|\n",
            "|Def Estimated: [14 15 19 35 17]| Att Labels: [15 15 18 35 17]\n",
            "\n",
            "|Epoch 063/100| time: 5.70|\n",
            "|Def Loss 0.0270 | Def Reward in ep 097|\n",
            "|Att Loss 0.0273 | Att Reward in ep 003|\n",
            "|Def Estimated: [ 8 21 20 35 16]| Att Labels: [ 9 22 20 34 15]\n",
            "\n",
            "|Epoch 064/100| time: 6.23|\n",
            "|Def Loss 0.0380 | Def Reward in ep 097|\n",
            "|Att Loss 0.0289 | Att Reward in ep 003|\n",
            "|Def Estimated: [13 32 11 32 12]| Att Labels: [14 32 11 29 14]\n",
            "\n",
            "|Epoch 065/100| time: 5.99|\n",
            "|Def Loss 0.0350 | Def Reward in ep 098|\n",
            "|Att Loss 0.0261 | Att Reward in ep 002|\n",
            "|Def Estimated: [12 23 20 25 20]| Att Labels: [13 23 20 24 20]\n",
            "\n",
            "|Epoch 066/100| time: 6.14|\n",
            "|Def Loss 0.0524 | Def Reward in ep 095|\n",
            "|Att Loss 0.0249 | Att Reward in ep 005|\n",
            "|Def Estimated: [14 22 19 31 14]| Att Labels: [15 22 18 32 13]\n",
            "\n",
            "|Epoch 067/100| time: 6.21|\n",
            "|Def Loss 0.0395 | Def Reward in ep 097|\n",
            "|Att Loss 0.0316 | Att Reward in ep 003|\n",
            "|Def Estimated: [21 18 13 29 19]| Att Labels: [20 18 14 31 17]\n",
            "\n",
            "|Epoch 068/100| time: 6.01|\n",
            "|Def Loss 0.0463 | Def Reward in ep 095|\n",
            "|Att Loss 0.0260 | Att Reward in ep 005|\n",
            "|Def Estimated: [15 20 23 24 18]| Att Labels: [16 20 22 21 21]\n",
            "\n",
            "|Epoch 069/100| time: 5.96|\n",
            "|Def Loss 0.0399 | Def Reward in ep 095|\n",
            "|Att Loss 0.0229 | Att Reward in ep 005|\n",
            "|Def Estimated: [11 23 13 37 16]| Att Labels: [12 23 14 34 17]\n",
            "\n",
            "|Epoch 070/100| time: 5.96|\n",
            "|Def Loss 0.0438 | Def Reward in ep 097|\n",
            "|Att Loss 0.0244 | Att Reward in ep 003|\n",
            "|Def Estimated: [11 32 15 29 13]| Att Labels: [12 32 15 30 11]\n",
            "\n",
            "|Epoch 071/100| time: 6.06|\n",
            "|Def Loss 0.0329 | Def Reward in ep 097|\n",
            "|Att Loss 0.0220 | Att Reward in ep 003|\n",
            "|Def Estimated: [13 19 28 24 16]| Att Labels: [13 19 28 25 15]\n",
            "\n",
            "|Epoch 072/100| time: 6.00|\n",
            "|Def Loss 0.0427 | Def Reward in ep 097|\n",
            "|Att Loss 0.0242 | Att Reward in ep 003|\n",
            "|Def Estimated: [ 7 33 16 30 14]| Att Labels: [ 7 32 16 31 14]\n",
            "\n",
            "|Epoch 073/100| time: 5.80|\n",
            "|Def Loss 0.0585 | Def Reward in ep 098|\n",
            "|Att Loss 0.0240 | Att Reward in ep 002|\n",
            "|Def Estimated: [10 17 13 46 14]| Att Labels: [11 16 14 45 14]\n",
            "\n",
            "|Epoch 074/100| time: 6.03|\n",
            "|Def Loss 0.0567 | Def Reward in ep 095|\n",
            "|Att Loss 0.0246 | Att Reward in ep 005|\n",
            "|Def Estimated: [10 21 20 34 15]| Att Labels: [12 21 22 29 16]\n",
            "\n",
            "|Epoch 075/100| time: 6.19|\n",
            "|Def Loss 0.0538 | Def Reward in ep 096|\n",
            "|Att Loss 0.0291 | Att Reward in ep 004|\n",
            "|Def Estimated: [14 26 16 33 11]| Att Labels: [16 25 15 33 11]\n",
            "\n",
            "|Epoch 076/100| time: 5.75|\n",
            "|Def Loss 0.0647 | Def Reward in ep 095|\n",
            "|Att Loss 0.0252 | Att Reward in ep 005|\n",
            "|Def Estimated: [10 18 22 34 16]| Att Labels: [12 19 20 34 15]\n",
            "\n",
            "|Epoch 077/100| time: 6.37|\n",
            "|Def Loss 0.0707 | Def Reward in ep 096|\n",
            "|Att Loss 0.0270 | Att Reward in ep 004|\n",
            "|Def Estimated: [16 20 15 33 16]| Att Labels: [19 18 14 32 17]\n",
            "\n",
            "|Epoch 078/100| time: 6.06|\n",
            "|Def Loss 0.0701 | Def Reward in ep 097|\n",
            "|Att Loss 0.0296 | Att Reward in ep 003|\n",
            "|Def Estimated: [14 20 20 29 17]| Att Labels: [13 20 21 31 15]\n",
            "\n",
            "|Epoch 079/100| time: 5.79|\n",
            "|Def Loss 0.0588 | Def Reward in ep 098|\n",
            "|Att Loss 0.0289 | Att Reward in ep 002|\n",
            "|Def Estimated: [ 8 15 20 42 15]| Att Labels: [ 9 15 20 40 16]\n",
            "\n",
            "|Epoch 080/100| time: 6.05|\n",
            "|Def Loss 0.0729 | Def Reward in ep 097|\n",
            "|Att Loss 0.0272 | Att Reward in ep 003|\n",
            "|Def Estimated: [11 25 18 27 19]| Att Labels: [10 25 18 26 21]\n",
            "\n",
            "|Epoch 081/100| time: 5.92|\n",
            "|Def Loss 0.0669 | Def Reward in ep 096|\n",
            "|Att Loss 0.0262 | Att Reward in ep 004|\n",
            "|Def Estimated: [ 9 32 21 24 14]| Att Labels: [10 33 20 21 16]\n",
            "\n",
            "|Epoch 082/100| time: 6.21|\n",
            "|Def Loss 0.0605 | Def Reward in ep 098|\n",
            "|Att Loss 0.0268 | Att Reward in ep 002|\n",
            "|Def Estimated: [11 23 21 22 23]| Att Labels: [12 23 21 21 23]\n",
            "\n",
            "|Epoch 083/100| time: 5.85|\n",
            "|Def Loss 0.0615 | Def Reward in ep 097|\n",
            "|Att Loss 0.0272 | Att Reward in ep 003|\n",
            "|Def Estimated: [14 20 14 33 19]| Att Labels: [13 20 15 32 20]\n",
            "\n",
            "|Epoch 084/100| time: 5.70|\n",
            "|Def Loss 0.0585 | Def Reward in ep 097|\n",
            "|Att Loss 0.0234 | Att Reward in ep 003|\n",
            "|Def Estimated: [10 22 14 35 19]| Att Labels: [10 22 14 34 20]\n",
            "\n",
            "|Epoch 085/100| time: 6.59|\n",
            "|Def Loss 0.0558 | Def Reward in ep 098|\n",
            "|Att Loss 0.0205 | Att Reward in ep 002|\n",
            "|Def Estimated: [21 22 14 26 17]| Att Labels: [23 22 13 25 17]\n",
            "\n",
            "|Epoch 086/100| time: 5.91|\n",
            "|Def Loss 0.0574 | Def Reward in ep 096|\n",
            "|Att Loss 0.0177 | Att Reward in ep 004|\n",
            "|Def Estimated: [15 20 16 36 13]| Att Labels: [15 22 15 34 14]\n",
            "\n",
            "|Epoch 087/100| time: 6.11|\n",
            "|Def Loss 0.0778 | Def Reward in ep 096|\n",
            "|Att Loss 0.0219 | Att Reward in ep 004|\n",
            "|Def Estimated: [16 23 11 28 22]| Att Labels: [16 24 11 29 20]\n",
            "\n",
            "|Epoch 088/100| time: 5.84|\n",
            "|Def Loss 0.0679 | Def Reward in ep 099|\n",
            "|Att Loss 0.0203 | Att Reward in ep 001|\n",
            "|Def Estimated: [ 7 32 20 27 14]| Att Labels: [ 7 32 21 27 13]\n",
            "\n",
            "|Epoch 089/100| time: 5.59|\n",
            "|Def Loss 0.0650 | Def Reward in ep 094|\n",
            "|Att Loss 0.0191 | Att Reward in ep 006|\n",
            "|Def Estimated: [11 20 15 32 22]| Att Labels: [11 22 16 29 22]\n",
            "\n",
            "|Epoch 090/100| time: 6.05|\n",
            "|Def Loss 0.0563 | Def Reward in ep 099|\n",
            "|Att Loss 0.0191 | Att Reward in ep 001|\n",
            "|Def Estimated: [12 29 12 35 12]| Att Labels: [12 29 12 34 13]\n",
            "\n",
            "|Epoch 091/100| time: 6.16|\n",
            "|Def Loss 0.0620 | Def Reward in ep 097|\n",
            "|Att Loss 0.0252 | Att Reward in ep 003|\n",
            "|Def Estimated: [14 25 11 33 17]| Att Labels: [14 26 12 31 17]\n",
            "\n",
            "|Epoch 092/100| time: 5.76|\n",
            "|Def Loss 0.0509 | Def Reward in ep 099|\n",
            "|Att Loss 0.0238 | Att Reward in ep 001|\n",
            "|Def Estimated: [ 9 31 15 23 22]| Att Labels: [ 9 31 15 24 21]\n",
            "\n",
            "|Epoch 093/100| time: 6.03|\n",
            "|Def Loss 0.0522 | Def Reward in ep 098|\n",
            "|Att Loss 0.0207 | Att Reward in ep 002|\n",
            "|Def Estimated: [ 9 21 20 31 19]| Att Labels: [ 9 21 20 29 21]\n",
            "\n",
            "|Epoch 094/100| time: 6.28|\n",
            "|Def Loss 0.0460 | Def Reward in ep 097|\n",
            "|Att Loss 0.0195 | Att Reward in ep 003|\n",
            "|Def Estimated: [19 19 18 27 17]| Att Labels: [21 17 18 27 17]\n",
            "\n",
            "|Epoch 095/100| time: 6.10|\n",
            "|Def Loss 0.0397 | Def Reward in ep 097|\n",
            "|Att Loss 0.0240 | Att Reward in ep 003|\n",
            "|Def Estimated: [12 23 21 27 17]| Att Labels: [11 23 21 28 17]\n",
            "\n",
            "|Epoch 096/100| time: 6.00|\n",
            "|Def Loss 0.0456 | Def Reward in ep 095|\n",
            "|Att Loss 0.0307 | Att Reward in ep 005|\n",
            "|Def Estimated: [12 19 20 34 15]| Att Labels: [15 19 20 32 14]\n",
            "\n",
            "|Epoch 097/100| time: 5.84|\n",
            "|Def Loss 0.0261 | Def Reward in ep 096|\n",
            "|Att Loss 0.0234 | Att Reward in ep 004|\n",
            "|Def Estimated: [13 17 21 35 14]| Att Labels: [14 17 22 33 14]\n",
            "\n",
            "|Epoch 098/100| time: 6.47|\n",
            "|Def Loss 0.0481 | Def Reward in ep 097|\n",
            "|Att Loss 0.0238 | Att Reward in ep 003|\n",
            "|Def Estimated: [17 29 16 27 11]| Att Labels: [17 27 17 27 12]\n",
            "\n",
            "|Epoch 099/100| time: 5.68|\n",
            "|Def Loss 0.0615 | Def Reward in ep 096|\n",
            "|Att Loss 0.0175 | Att Reward in ep 004|\n",
            "|Def Estimated: [ 9 27 12 34 18]| Att Labels: [10 28 12 31 19]\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "w56BPg3zo0DC",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "W2QzwrilomWO",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "OoBlm8f7fW_C",
        "colab_type": "code",
        "outputId": "415bce2e-2faa-484f-8eb7-9b43b23bf675",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 302
        }
      },
      "cell_type": "code",
      "source": [
        "if not os.path.exists('models'):\n",
        "    os.makedirs('models')\n",
        "# Save trained model weights and architecture, used in test\n",
        "defender_agent.model_network.model.save_weights(\"models/defender_agent_model.h5\", overwrite=True)\n",
        "with open(\"models/defender_agent_model.json\", \"w\") as outfile:\n",
        "    json.dump(defender_agent.model_network.model.to_json(), outfile)\n",
        "\n",
        "\n",
        "    \n",
        "if not os.path.exists('results'):\n",
        "    os.makedirs('results')    \n",
        "# Plot training results\n",
        "plt.figure(1)\n",
        "plt.subplot(211)\n",
        "plt.plot(np.arange(len(def_reward_chain)),def_reward_chain,label='Defense')\n",
        "plt.plot(np.arange(len(att_reward_chain)),att_reward_chain,label='Attack')\n",
        "plt.title('Total reward by episode')\n",
        "plt.xlabel('n Episode')\n",
        "plt.ylabel('Total reward')\n",
        "plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,\n",
        "       ncol=2, mode=\"expand\", borderaxespad=0.)\n",
        "\n",
        "plt.subplot(212)\n",
        "plt.plot(np.arange(len(def_loss_chain)),def_loss_chain,label='Defense')\n",
        "plt.plot(np.arange(len(att_loss_chain)),att_loss_chain,label='Attack')\n",
        "plt.title('Loss by episode')\n",
        "plt.xlabel('n Episode')\n",
        "plt.ylabel('loss')\n",
        "plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,\n",
        "       ncol=2, mode=\"expand\", borderaxespad=0.)\n",
        "plt.tight_layout()\n",
        "#plt.show()\n",
        "plt.savefig('results/train_adv.eps', format='eps', dpi=1000)"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<matplotlib.figure.Figure at 0x7f6e03fb3c50>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "metadata": {
        "id": "HHpLDW9kfeQL",
        "colab_type": "code",
        "outputId": "e4a20a64-5f88-4f60-be3d-65aac1e3cd21",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1081
        }
      },
      "cell_type": "code",
      "source": [
        "bins=np.arange(24) -0.5\n",
        "# Plot attacks distribution alongside\n",
        "plt.figure(2,figsize=[12,5])\n",
        "plt.title(\"Attacks distribution throughout  episodes\")\n",
        "for indx,e in enumerate([0,70,90]):\n",
        "    plt.subplot(1,3,indx+1)\n",
        "    plt.hist(attacks_by_epoch[e],bins=bins,width=0.9,align='left')\n",
        "    plt.xlabel(\"{} epoch\".format(e))\n",
        "    plt.xticks(bins, env.attack_names, rotation=90)\n",
        "\n",
        "\n",
        "plt.tight_layout()\n",
        "plt.savefig('results/Attacks_distribution.svg', format='svg', dpi=1000)\n",
        "\n",
        "\n",
        " # Plot attacks distribution alongside\n",
        "plt.figure(3,figsize=[10,10])\n",
        "plt.title(\"Attacks (mapped) distribution throughout  episodes\")\n",
        "for indx,e in enumerate([0,10,20,30,40,60,70,80,90]):\n",
        "    plt.subplot(3,3,indx+1)\n",
        "    plt.bar(range(5),attack_labels_list[e],tick_label =['Normal','Dos','Probe','R2L','U2R'])\n",
        "    plt.xlabel(\"{} epoch\".format(e))\n",
        "plt.tight_layout()\n",
        "plt.savefig('results/Attacks_mapped_distribution.svg', format='svg', dpi=1000)"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1gAAAFgCAYAAACmKdhBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzs3Xm4ZFV57/Fv0w1c0VY70KgookZ5\nRU1QoyKiMoREjCIxMnivE6Li7DXBgatRlBDFASdQghNOIahoggQVRSZBcJ7R1xFxtoFWUQIC3feP\ntYuuU111atepXeP5fp6nnz6natXea9ep/Ttn7bX2Wis2btyIJEmSJGl4W0y6ApIkSZI0L2xgSZIk\nSVJDbGBJkiRJUkNsYEmSJElSQ2xgSZIkSVJDVjW9wXXrrh56WsI1a7Zh/fprlk25Waijxzx8uVmo\nYxPl1q5dvaLvBhq2HHJnFuroMQ9fbhbqOI3HbO4MVm6S+/aYx1duFuo468fcK3umsgdr1aqVy6rc\nJPftMY+v3CT3PcljnhWz8F5Oex095uHLTXLf83TMs2Ke3vNpLzfJfXvM4ys36X23TGUDS5IkSZJm\nkQ0sSZIkSWqIDSxJkiRJaogNLEmSJElqiA0sSZIkSWqIDSxJkiRJaogNLEmSJElqSOMLDUvSoCLi\nXsDpwBsz84SI2BE4GdgSuB54fGb+apJ1lDRfzB1Jo2IPlqSJioibA8cDn2l7+Bjg7Zm5J/CfwD9N\nom6S5pO5I2mUbGBJmrTrgL8DftH22LOAj1RfrwO2HXelJM01c0fSyDhEUAIOO/acvmXefeQ+Y6jJ\n8pOZNwA3RET7Y38EiIiVwLOBoxfbxpo127Bq1cra+9z/iNP7ljnjuAN6Prd27epa+2m63CT37TGP\nr9wk9z1Px7wYc2c025z2cpPct8c8vnKT3jfYwJI0pao/ct4PnJOZn1ms7Pr11zS+/3Xrru76+Nq1\nq3s+N8pyk9y3xzy+crNQx2k85iYaXbB8cmcU25z2crNQR495+HLj3nev7HGIoKRpdTLw/cx85aQr\nImnZMHckDc0GlqSpExGPA/6UmUdNui6SlgdzR1JTHCIoaaIi4q+A44A7AddHxIHA9sC1EXFeVezS\nzHzWZGooad6YO5JGyQaWpInKzC8De026HpKWD3NH0ig5RFCSJEmSGmIDS5IkSZIaYgNLkiRJkhpi\nA0uSJEmSGmIDS5IkSZIaYgNLkiRJkhpiA0uSJEmSGmIDS5IkSZIaYgNLkiRJkhpiA0uSJEmSGmID\nS5IkSZIaYgNLkiRJkhpiA0uSJEmSGmIDS5IkSZIaYgNLkiRJkhpiA0uSJEmSGmIDS5IkSZIasqpf\ngYi4BfA+YA2wNfDKzDxr1BWTJEmSpFlTpwfrUCAzc2/gQODNI62RJEmSJM2oOg2sK4Btq6/XVN9L\nkiRJkjr0bWBl5qnAHSPiB8AFwAtGXitJkiRJmkF17sF6PHB5Zu4XEbsC7wLu16v8mjXbsGrVyqEr\ntnbt6qkot/8Rp/d9zRnHHTD0fgcpOy/lJrnvQepY5zXzdMyjfA8lSZLmXd8GFrAHcBZAZn49InaI\niJWZeWO3wuvXXzN0pdauXc26dVdPbblOvV4zyPam/ZhH8R7OQh3b+XOuV86GlyRJWs7q3IP1A2A3\ngIjYCfhDr8aVJEmSJC1ndXqwTgLeHRHnV+WfMdoqSZIkSdJs6tvAysw/AAePoS6SJEmSNNPqDBGU\nJEmSJNVgA0uSJEmSGmIDS5IkSZIaYgNLkiRJkhpiA0uSJEmSGlJnmnZJGqmIuBdwOvDGzDwhInYE\n3g+sBH4JPCEzr5tkHSXNF3NH0qjYgyVpoiLi5sDxwGfaHj4aeGtmPoSy2Plhk6ibpPlk7kgaJRtY\nkibtOuDvgF+0PbYX8LHq6zOAfcdcJ0nzzdyRNDIOEZQ0UZl5A3BDRLQ/fPO2oTm/AW632DbWrNmG\nVatWNlqvtWtXL+m5UZab5L495vGVm+S+5+mYF2PujGab015ukvv2mMdXbtL7BhtYkqbfin4F1q+/\npvGdrlt3ddfH165d3fO5UZab5L495vGVm4U6TuMxN9Ho6jDXuTOKbU57uVmoo8c8fLlx77tX9jhE\nUNI0+kNE3Kz6+vYsHMYjSaNg7khqhA0sSdPobOAx1dePAT45wbpIWh7MHUmNcIigpImKiL8CjgPu\nBFwfEQcCjwPeExFPB34CvHdyNZQ0b8wdSaNkA0vSRGXmlymzd3X6mzFXRdIyYe5IGiWHCEqSJElS\nQ2xgSZIkSVJDbGBJkiRJUkNsYEmSJElSQ2xgSZIkSVJDbGBJkiRJUkNsYEmSJElSQ2xgSZIkSVJD\nbGBJkiRJUkNsYEmSJElSQ2xgSZIkSVJDbGBJkiRJUkNsYEmSJElSQ2xgSZIkSVJDbGBJkiRJUkNs\nYEmSJElSQ2xgSZIkSVJDbGBJkiRJUkNsYEmSJElSQ2xgSZIkSVJDbGBJkiRJUkNsYEmSJElSQ2xg\nSZIkSVJDbGBJkiRJUkNsYEmSJElSQ2xgSZIkSVJDbGBJkiRJUkNsYEmSJElSQ2xgSZIkSVJDbGBJ\nkiRJUkNW1SkUEY8DXgTcALw8M88caa0kLWsRcQvgfcAaYGvglZl51mRrJWmemTuSmtK3BysitgWO\nAh4MPBI4YNSVkrTsHQpkZu4NHAi8ebLVkbQMHIq5I6kBdXqw9gXOzsyrgauBw0dbJUniCuAvq6/X\nVN9L0iiZO5IasWLjxo2LFoiIFwO7AH9GCZxXZOZnepW/4YYbN65atbLRSgLsf8TpfcuccVzznWuT\n2u+k973c1H2v65RrlV3GVjSxkYj4JHBXSu48IjMv6VV20Nzx3JLmjrkjaRK6Zk+dHqwVwLbAo4Gd\ngHMjYqfM7NoyW7/+miXXsGXt2tWsW3f1wK/r9Zq625vUfie570mVm5U6thvkNbP6c2mi3Nq1q/u+\nvp+IeDxweWbuFxG7Au8C7terfBO502nafoaT3LfHPL5ys1DHaTxmc2ewcqPY5rSXm4U6eszDlxv3\nvntlT51ZBH8NfC4zb8jMH1KGCa6t8TpJWqo9gLMAMvPrwA4R0XzXuCRtYu5IakSdBtangH0iYotq\nwotb4LhkSaP1A2A3gIjYCfhDZt442SpJmnPmjqRG9G1gZebPgdOAS4BPAM/NzA2jrpikZe0k4E4R\ncT5wCvCMCddH0vwzdyQ1otY6WJl5EiV4JGnkMvMPwMGTroek5cPckdSUOkMEJUmSJEk12MCSJEmS\npIbYwJIkSZKkhtjAkiRJkqSG2MCSJEmSpIbYwJIkSZKkhtjAkiRJkqSG2MCSJEmSpIbYwJIkSZKk\nhtjAkiRJkqSG2MCSJEmSpIbYwJIkSZKkhtjAkiRJkqSG2MCSJEmSpIasmnQFJGlaHXbsOX3LvPvI\nfSay31Htezma1M9ZGoY5IU0ve7AkSZIkqSE2sCRJkiSpITawJEmSJKkhNrAkSZIkqSE2sCRJkiSp\nITawJEmSJKkhTtPekHmaLnUUUxY3vc2625vk9MvTPMX3LHwOJUmSZpE9WJIkSZLUEBtYkiRJktQQ\nG1iSJEmS1BAbWJIkSZLUEBtYkiRJktQQG1iSJEmS1BAbWJIkSZLUEBtYkiRJktQQG1iSJEmS1JBV\n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\npwAfrx7ras2abVi1qtm/g9auXT3V5Sa571GU2/+I02uVPeO4Axrd5iDbG7bcID/bpe57XMfc+VyT\n+x10302Zx9wZdJvTfs6MIifmodwk971cjnnQ3LGBJWlqRcQBlD90/naxcuvXX9P4vtetu3qqy01y\n3x7z4OXWrl090HE2ue+myy31WJr4Offad5ONrnnKnVFsc9o/Z03se9bKTXLfy+GYF/ss9soeG1iS\nplJEPAx4KbBfZv5u0vWRNP/MHUlNsIElaepExK2A1wH7ZuZVk66PpPln7khqig0sSdPoEGA74EMR\n0XrsiZl5+eSqJGnOmTuSGmEDS9LUycy3A2+fdD0kLR/mjqSmOE27JEmSJDXEBpYkSZIkNcQGliRJ\nkiQ1xAaWJEmSJDXEBpYkSZIkNcQGliRJkiQ1xAaWJEmSJDVk2a6Dddix5/Qt8+4j9xlDTYY3T8ci\nSZIkzTJ7sCRJkiSpITawJEmSJKkhNrAkSZIkqSE2sCRJkiSpITawJEmSJKkhNrAkSZIkqSHLdpp2\nSZJGwaUzpMF4zmje2IMlSZIkSQ2xgSVJkiRJDbGBJUmSJEkNsYElSZIkSQ2xgSVJkiRJDbGBJUmS\nJEkNsYElSZIkSQ2xgSVJkiRJDbGBJUmSJEkNsYElSZIkSQ2xgSVJkiRJDbGBJUmSJEkNsYElSZIk\nSQ2xgSVJkiRJDbGBJUmSJEkNWVWnUES8EXggsBH4v5n5xZHWStKyZ+5IGjdzR1IT+vZgRcSewN0y\nc3fgKcBbRl4rScuauSNp3MwdSU2pM0Twr4H/AsjM7wBrIuKWI62VpOXO3JE0buaOpEas2Lhx46IF\nIuLtwJmZeXr1/WeBp2Tm98ZQP0nLkLkjadzMHUlNWcokFysar4UkLc7ckTRu5o6kJanTwPoFcNu2\n73cAfjma6kgSYO5IGj9zR1Ij6jSwPgUcCBAR9wV+kZlXj7RWkpY7c0fSuJk7khrR9x4sgIg4Fngo\nsAF4dmZ+fdQVk7S8mTuSxs3ckdSEWg0sSZIkSVJ/S5nkQpIkSZLUhQ0sSZIkSWqIDSxphCLCaX4l\njZW5I2nczJ2FbGBJA4qI07o8dkmP4ueNtjbDi4hVXR77s0nURVJvA2TPeaOvzXDMHWk2mDtLs9mO\nxikiXgf0nGUjM1/UUf4lmfmqtu/XAidm5oFtj91xsX1m5uUd21wFHATcPjNfHxH3KsXy+gGP5eTM\n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\n",
            "text/plain": [
              "<matplotlib.figure.Figure at 0x7f6e03ff5630>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<matplotlib.figure.Figure at 0x7f6dea2d0780>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "metadata": {
        "id": "GdEEgnejoANJ",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "MLhFt4v2oA5r",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "-3z12k-CoBqI",
        "colab_type": "text"
      },
      "cell_type": "markdown",
      "source": [
        "# TEST"
      ]
    },
    {
      "metadata": {
        "id": "k2EScB5ZoA8t",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "from keras.models import model_from_json\n",
        "\n",
        "import itertools\n",
        "from sklearn.metrics import f1_score\n",
        "from sklearn.metrics import accuracy_score, precision_score, recall_score\n",
        "from sklearn.metrics import  confusion_matrix"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "i1PgEGysoOlU",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "\n",
        "def plot_confusion_matrix(cm, classes,\n",
        "                          normalize=False,\n",
        "                          title='Confusion matrix',\n",
        "                          cmap=plt.cm.Blues):\n",
        "    \"\"\"\n",
        "    This function prints and plots the confusion matrix.\n",
        "    Normalization can be applied by setting `normalize=True`.\n",
        "    \"\"\"\n",
        "    if normalize:\n",
        "        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n",
        "        print(\"Normalized confusion matrix\")\n",
        "    else:\n",
        "        print('Confusion matrix, without normalization')\n",
        "\n",
        "    print(cm)\n",
        "\n",
        "    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n",
        "    plt.title(title)\n",
        "    plt.colorbar()\n",
        "    tick_marks = np.arange(len(classes))\n",
        "    plt.xticks(tick_marks, classes, rotation=45)\n",
        "    plt.yticks(tick_marks, classes)\n",
        "\n",
        "    fmt = '.2f' if normalize else 'd'\n",
        "    thresh = cm.max() / 2.\n",
        "    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n",
        "        plt.text(j, i, format(cm[i, j], fmt),\n",
        "                 horizontalalignment=\"center\",\n",
        "                 color=\"white\" if cm[i, j] > thresh else \"black\")\n",
        "\n",
        "    plt.tight_layout()\n",
        "    plt.ylabel('True label')\n",
        "    plt.xlabel('Predicted label')\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "5cSeFJb3oPVT",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        "formated_test_path = \"formated_test_adv.data\"\n",
        "\n",
        "with open(\"models/defender_agent_model.json\", \"r\") as jfile:\n",
        "    model = model_from_json(json.load(jfile))\n",
        "model.load_weights(\"models/defender_agent_model.h5\")\n",
        "\n",
        "model.compile(loss=huber_loss,optimizer=\"sgd\")\n",
        "\n",
        "\n",
        "# Define environment, game, make sure the batch_size is the same in train\n",
        "env_test = RLenv('test',formated_test_path = formated_test_path)\n",
        "\n",
        "\n",
        "total_reward = 0    \n",
        "\n",
        "\n",
        "true_labels = np.zeros(len(env_test.attack_types),dtype=int)\n",
        "estimated_labels = np.zeros(len(env_test.attack_types),dtype=int)\n",
        "estimated_correct_labels = np.zeros(len(env_test.attack_types),dtype=int)\n",
        "\n",
        "#states , labels = env.get_sequential_batch(test_path,batch_size = env.batch_size)\n",
        "states , labels = env_test.get_full()\n",
        "\n",
        "\n",
        "start_time=time.time()\n",
        "q = model.predict(states)\n",
        "actions = np.argmax(q,axis=1)        "
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "metadata": {
        "id": "8hFU1HF1oYFG",
        "colab_type": "code",
        "outputId": "84467272-00c9-4381-a829-c58c1d86a5a0",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 151
        }
      },
      "cell_type": "code",
      "source": [
        "maped=[]\n",
        "for indx,label in labels.iterrows():\n",
        "    maped.append(env_test.attack_types.index(env_test.attack_map[label.idxmax()]))\n",
        "\n",
        "labels,counts = np.unique(maped,return_counts=True)\n",
        "true_labels[labels] += counts\n",
        "\n",
        "\n",
        "\n",
        "for indx,a in enumerate(actions):\n",
        "    estimated_labels[a] +=1              \n",
        "    if a == maped[indx]:\n",
        "        total_reward += 1\n",
        "        estimated_correct_labels[a] += 1\n",
        "\n",
        "\n",
        "action_dummies = pd.get_dummies(actions)\n",
        "posible_actions = np.arange(len(env_test.attack_types))\n",
        "for non_existing_action in posible_actions:\n",
        "    if non_existing_action not in action_dummies.columns:\n",
        "        action_dummies[non_existing_action] = np.uint8(0)\n",
        "labels_dummies = pd.get_dummies(maped)\n",
        "\n",
        "normal_f1_score = f1_score(labels_dummies[0].values,action_dummies[0].values)\n",
        "dos_f1_score = f1_score(labels_dummies[1].values,action_dummies[1].values)\n",
        "probe_f1_score = f1_score(labels_dummies[2].values,action_dummies[2].values)\n",
        "r2l_f1_score = f1_score(labels_dummies[3].values,action_dummies[3].values)\n",
        "u2r_f1_score = f1_score(labels_dummies[4].values,action_dummies[4].values)\n",
        "    \n",
        "\n",
        "Accuracy = [normal_f1_score,dos_f1_score,probe_f1_score,r2l_f1_score,u2r_f1_score]\n",
        "Mismatch = estimated_labels - true_labels\n",
        "\n",
        "acc = float(100*total_reward/len(states))\n",
        "print('\\r\\nTotal reward: {} | Number of samples: {} | Accuracy = {:.2f}%'.format(total_reward,\n",
        "      len(states),acc))\n",
        "outputs_df = pd.DataFrame(index = env_test.attack_types,columns = [\"Estimated\",\"Correct\",\"Total\",\"F1_score\"])\n",
        "for indx,att in enumerate(env_test.attack_types):\n",
        "   outputs_df.iloc[indx].Estimated = estimated_labels[indx]\n",
        "   outputs_df.iloc[indx].Correct = estimated_correct_labels[indx]\n",
        "   outputs_df.iloc[indx].Total = true_labels[indx]\n",
        "   outputs_df.iloc[indx].F1_score = Accuracy[indx]*100\n",
        "   outputs_df.iloc[indx].Mismatch = abs(Mismatch[indx])\n",
        "    \n",
        "    \n",
        "print(outputs_df)"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "\r\n",
            "Total reward: 18422 | Number of samples: 22544 | Accuracy = 81.72%\n",
            "       Estimated Correct Total F1_score\n",
            "normal     11103    9068  9712  87.1295\n",
            "DoS         6908    6424  7458  89.4334\n",
            "Probe       2547    1989  2421  80.0725\n",
            "R2L         1767     902  2753  39.9115\n",
            "U2R          219      39   200  18.6158\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "HBxETWRcocbS",
        "colab_type": "code",
        "outputId": "0e1e5a99-16ee-4316-b9f3-26cabd6f30e5",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 441
        }
      },
      "cell_type": "code",
      "source": [
        "fig, ax = plt.subplots()\n",
        "fig.set_size_inches(10, 6)\n",
        "width = 0.35\n",
        "pos = np.arange(len(true_labels))\n",
        "p1 = plt.bar(pos, estimated_correct_labels,width,color='g')\n",
        "p1 = plt.bar(pos+width,\n",
        "             (np.abs(estimated_correct_labels-true_labels)),width,\n",
        "             color='r')\n",
        "p2 = plt.bar(pos+width,np.abs(estimated_labels-estimated_correct_labels),width,\n",
        "             bottom=(np.abs(estimated_correct_labels-true_labels)),\n",
        "             color='b')\n",
        "\n",
        "ax.yaxis.set_tick_params(labelsize=15)\n",
        "ax.set_xticks(pos+width/2)\n",
        "ax.set_xticklabels(env.attack_types,rotation='vertical',fontsize = 'xx-large')\n",
        "\n",
        "#ax.set_yscale('log')\n",
        "\n",
        "#ax.set_ylim([0, 100])\n",
        "#ax.set_title('Test set scores',fontsize = 'xx-large')\n",
        "#ax.set_title('Test set scores, Acc = {:.2f}'.format(acc))\n",
        "plt.legend(('Correct estimated','False negative','False positive'),fontsize = 'x-large')\n",
        "plt.tight_layout()\n",
        "#plt.show()\n",
        "plt.savefig('results/test_adv_imp.svg', format='svg', dpi=1000)\n"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAsgAAAGoCAYAAABbtxOxAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4yLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvNQv5yAAAIABJREFUeJzs3XeYVNX9x/H3wgIGBUEBAaUImmNL\nkVhQsaAoKrYgWMHys2BDVLAlKmLDhgE0qISoUWOixooigihFscTe8IglNtoCS1Vpu78/7rBelgUW\nZXdg9v16Hp9h7zlz5jt7WfzsmXPPzSsuLkaSJElSolq2C5AkSZLWJwZkSZIkKcWALEmSJKUYkCVJ\nkqQUA7IkSZKUkp/tAn6pgoL5bsNRDvXr16aw8Ptsl6Es8fxXXZ77qstzX3V57suvYcM6eWUddwa5\nisjPr57tEpRFnv+qy3NfdXnuqy7P/S9nQJYkSZJSDMiSJElSigFZkiRJSjEgS5IkSSkGZEmSJCnF\ngCxJkiSlGJAlSZKkFAOyJEmSlGJAliRJklIMyJIkSVKKAVmSJElKMSBLkiRJKfnZLkCSJOWuRkPq\nVvprzjhnXqW/Zi6aNm0qJ5xwNHfeeQ8hbJftcsrUrt0uXHvtjbRv32GdjmtAliRJVd7UqVP4xz/+\nzuuvv8rcuXOpU6cOv//9zpx00mm0br1NtssrMX/+fEaPHknnzl0rZPwRI4az225tadCgIY0bN+HF\nFydWyOsATJ4cmTmzgD32aFdhr/FzucRCkiRVaV9++QWnndadvLw87rzz74wZ8zJ33XUPderUpUeP\nU5g06aNsl1jirbfe4IknHq2QsZctW8bgwbcxc2ZBhYxf2jPPPMWrr75SKa+1tpxB/pmy8ZHRL1Hc\ntzjbJUiStF667bab2HbbwKWXXlFyrEmTpvTpczkbb7wJs2bNAqCoqIh///tBhg9/kunTp9Oo0RZ0\n63YShx12FADXX381y5YtY+HCBbzzztuMGjWO8847kxC258MP3+f77xfywAOPsHDhAm6//S+88cZr\nzJs3l223/TXnn9+b7bffEYB58+YyaNCtTJz4CtWq5bHHHu246KJLGD9+LP37X0NRURH7778ngwbd\nyW9+87uV3s9//vMf7rnnXr777lvq1atP587HcMIJ3QEoLCxkwIAbeeedN1m8eDEtWmzNOeecT5s2\nu9ChQzuWLFnC2WefRqdOR3DiiSfTtesRDBt2P9tttwNduhzOsceeyOuvT+Tdd99miy0a069ffyZM\nGMtjjz1McXExJ598OsccczwA06ZNY+DAm/nww/dZsmQJ2223I717X0rz5i246abreOaZp6hWrRrP\nPfcMo0dPYMmSJQwdOoSxY19k9uyZNGvWgrPOOo+2bfcEYO7cOdxwQz/eeedt6tWrx3nnXVhhfyec\nQZYkSVVWYWEh77zzFscee0KZ7Wef3ZN27fYB4OmnH+ehhx7gyiuvYdSocZx99nncckt/3n337ZL+\nr702kQMO6MjIkS+VHHvhhZH06HEu99//MAD9+1/L9OnTGDbsfp59dgy77tqWiy++gEWLfixpnzNn\nLg8//AT//OdjfPXV/7jjjoEcfHAnTjrp/2jZcmtefHFimeF44sSXueGGG7jwwkt4/vlxXH31DTzw\nwL2MHTsGgKFDh/D99wt55JGneO65lzjkkE5cc82VLF26lIceegyAO+/8O336XF7m9+Oxxx7hzDPP\n4emnn6dWrY245JILqFWrFk888RzHHdeNO+8czMKFCwC46aZryc/P57HHnuGpp56nTp1NuPHGawG4\n9NIr+N3vdubIIzszevSEktrefPN1Bg0awvPPj6NLl2P405/6lMxoDx58G7NmzeLhh59g2LD7GT16\nZHlO8c9iQJYkSVXWlCnfAdC8eYs19n3qqcc54og/ssMOO5Gfn8++++7P7363My+8MKqkT926dTno\noIOpVu2niLX11q1p02YX8vLymDNnDuPGvcgZZ5zNZpttTq1atTj11DMoLi5i4sSXmTt3Dq+8Mp6T\nTjqVunU3pV69elx++VXst98B5Xo/Tz31GEcccQS//30bqlevzk47/YZDDz2cESOGA7BgwXzy82tQ\nq9ZG5Ofnc/TRx/LEEyPIzy/fooLdd2/Lr3+9HbVrb8wuu+zK999/z3HHdaNGjRq0a7cvS5YsYfr0\naQDceOMArrzyGmrV2oiNNtqIffbZn08++bjMcYuKihg+/Am6dTuVpk23JD8/n8MOO4qWLVsxalQS\nhMeOHUPXrsdRv/5m1K27KSeddGq5av45XGIhSZKqvKKiZWvsM2XKd7Rs2WqFY1tu2YwpU74t+bpJ\nk6YrPa9Jky1L/vztt99QXFzMeeeduUKfZcuWMW3aNKZOnUJRUdEK47Rq1ZpWrVqX6318883XvP76\n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\ntWjRkm23/TXjxr1YcqywcDbvvfcOBx10MIsWLeLCC89lm2225fHHn+Xhh59i0aJF9O9/7S84E5XH\ngCxJkrQajRs3Zvjw0ey/fwcgCYfbb78DkyZ9vFLfhQsXUlRURO3aG5OXl0fjxk24995/0rlzV4qK\nihg+/Am6dTuVpk23JD8/n8MOO4qWLVsxatTIVb5+q1at2X//DuTn59OhQ0eqV6/OV199ucrxtt12\nW0aNGklRURGvv/4qXbocx+abN6BBg4acfPL/UVxcXDL2RRddwm233cEmm2xCjRo1OOCAA5kxYzqz\nZs1c4/flgAMOYty4l0q+HjfuJRo12oLf/OZ3vPbaKyxYsIAzzzyHWrU2ol69evTocS6vvvoyhYWF\na/PtzwqXWEiSpCrv7rvvYNiwO1c4VrNmTUaOHAvAM888ydNPP0lBwXSKi4tZunQpDRo0XGmcli23\n5qijunDuuaezww47sssuu3PQQYfQrFlzCgtns2DBAq677iquv75vyXOKioqYPv23q6xtq62alfw5\nLy+PmjVrsmjRolWOV1xczHbb7ci8efNYsmQJTZtuWdK24447rTD21Knfcfvtf+Gjjz5cYWZ58eLF\na/iOQYcOHbn77r/y3XffsuWWWzF27Bg6dOhIXl4eX3/9NT/88D0HHrj3Cs+pVq0a06dPpX79+msc\nP5sMyJIkqcpb3UV6I0YMZ9iwu7nmmv60bbsn+fn59O59fpl98/Ly6NPnMk488SQmTBjHyy+P4/77\n7+GGG27ld79L1gUPGHA7bdrsUu7aqlUr+wP/WrU2KnO8hg3rUFAwn8LC2QDk59dI1ffTWEVFRfTp\n04tttvk199//bxo0aMhHH31Ijx6nlKuuxo2bsOOOv2Hs2DEcdtiRvPPOW/Tq1SdTWy0aNdqCxx57\nptzvc33iEgtJkqTV+OijD9hhhx1p124f8vPzWbp0KV988VmZfYuKipg3by5NmjTlmGOOZ/Dgu+jQ\noSNPP/04m2yyCfXq1Wfy5LjCc6ZOnbLCsofyWtV43377LcXFxdStuynVq1dnypTvStomTfqo5M+F\nhbOZMuU7unQ5tmQ2PMZJa1VDhw4HMWHCOMaPH0urVq3ZeutWADRr1oyZMwtWWE6xaNGici3dWB8Y\nkCVJklajSZOmfPPN18yePYtZs2Zy6639qVevHgUFM1bqO2bMKE4++XgmT/6U4uLiTAj9lmbNWgDQ\n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\nNGnlALhw4UKKioqoXXtj8vLyaNy4Cffe+086d+5KUVERw4c/Qbdup9K06Zbk5+dz2GFH0bJlK0aN\nGrnK199mm23p0KEj+fn57L33foSwHRMmjAXg6aef4IQTTqJFi5bUqFGDo48+li222IKxY5NZ5AUL\n5rPRRr8iPz+fjTfehD//+Wquuab/Wr3/tm33Ij8/n9deexWA4uJixo17iYMOOiRTw+McffQxtG69\nDdWrV2ePPdqx557tGDFi5V8gNhTl2sUixvg+SchdVfvdwN2raf8GOHINr7HaMSRJkirK3XffwbBh\nd65wrGbNmowcORaAZ555kqeffpKCgukUFxezdOnSMtfqtmy5NUcd1YVzzz2dHXbYkV122Z2DDjqE\nZs2aU1g4mwULFnDddVdx/fV9S55TVFTE9Om/XWVtzZq1WOHrJk22pKCggHnz5jF//jxattx6hfYW\nLVqUzCCfc875/OUvN/Pcc8PZddfd2W+/A9h55z+s1femRo0a7LNPe8aPf5F9923PBx+8x7x589h3\n3/YAfPPN1/ztb3fy97//FOOKiorYffc91up11ifl3eZNkiQpZ63uIr0RI4YzbNjdXHNNf9q23ZP8\n/Hx69z6/zL55eXn06XMZJ554EhMmjOPll8dx//33cMMNt/K73+0MwIABt9OmzS7lrq2oaMW1zsXF\nxVSrlseSJYtX+Zy8vDwADj30cPbeez8mTpzAxIkT6N27J127Hs/ZZ/cs9+tDssziqqsuY+nSpbz0\n0hj22mtvNt54EwBq1qxFz54X0qnTEWs15vqsPGuQJUmSqqyPPvqAHXbYkXbt9iE/P5+lS5fyxRef\nldm3qKiIefPm0qRJU4455ngGD76LDh068vTTj7PJJptQr159Jk+OKzxn6tQpFBevelfb5bPB6f6N\nGjWmfv3NqF17Yz7//KdaioqK+Pzzz9lqq+YAzJkzhzp16tCx46H069efiy66lCeeWPsVrH/4w67U\nqFGTt976L+PGvchBB/2002+zZs2YPPnTFfpPmzZtlRcxbggMyJIkSavRpElTvvnma2bPnsWsWTO5\n9db+1KtXj4KCGSv1HTNmFCeffDyTJ39KcXExhYWzmTLl25JlEp07d+Whhx7gk08msWzZMl55ZQLd\nux/Dp5/GlcZabvLkyPjxY1m6dCkTJozl008/Yd9921OtWjUOOaQT//73P/n2229YvHgxDz10P3Pn\n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\nAABJRU5ErkJggg==\n",
            "text/plain": [
              "<matplotlib.figure.Figure at 0x7f6dea416d68>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "metadata": {
        "id": "FBVTk9aujCuI",
        "colab_type": "code",
        "outputId": "63d87333-7655-468a-aa89-b45fdd1e3957",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "cell_type": "code",
      "source": [
        "estimated_correct_labels"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([9068, 6424, 1989,  902,   39])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 18
        }
      ]
    },
    {
      "metadata": {
        "id": "UphioXJOjSpn",
        "colab_type": "code",
        "outputId": "70c9c724-c985-4815-9232-8078c1ac400a",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "cell_type": "code",
      "source": [
        "estimated_labels"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([11103,  6908,  2547,  1767,   219])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 19
        }
      ]
    },
    {
      "metadata": {
        "id": "_XrjAwLzjbWf",
        "colab_type": "code",
        "outputId": "fd943f8e-fa42-488f-8319-7eb6f2da087a",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "cell_type": "code",
      "source": [
        "true_labels"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([9712, 7458, 2421, 2753,  200])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 20
        }
      ]
    },
    {
      "metadata": {
        "id": "Jw9xTn9EkMku",
        "colab_type": "code",
        "outputId": "388a29de-6718-4c6d-90f6-15874ab6df72",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "cell_type": "code",
      "source": [
        "np.abs(estimated_correct_labels-true_labels) # false negative"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([ 644, 1034,  432, 1851,  161])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 21
        }
      ]
    },
    {
      "metadata": {
        "id": "OSneeTpxkYiU",
        "colab_type": "code",
        "outputId": "40f73413-c3b6-4a8d-c103-eaa32d0f5e04",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 34
        }
      },
      "cell_type": "code",
      "source": [
        "np.abs(estimated_labels-estimated_correct_labels)  #false positive"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "array([2035,  484,  558,  865,  180])"
            ]
          },
          "metadata": {
            "tags": []
          },
          "execution_count": 22
        }
      ]
    },
    {
      "metadata": {
        "id": "O0Z8IHZhonlP",
        "colab_type": "code",
        "outputId": "b27f64cd-b3ec-4016-8907-8f6aed7ca7a8",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 513
        }
      },
      "cell_type": "code",
      "source": [
        "aggregated_data_test = np.array(maped)\n",
        "\n",
        "print('Performance measures on Test data')\n",
        "print('Accuracy =  {:.4f}'.format(accuracy_score( aggregated_data_test,actions)))\n",
        "print('F1 =  {:.4f}'.format(f1_score(aggregated_data_test,actions, average='weighted')))\n",
        "print('Precision_score =  {:.4f}'.format(precision_score(aggregated_data_test,actions, average='weighted')))\n",
        "print('recall_score =  {:.4f}'.format(recall_score(aggregated_data_test,actions, average='weighted')))\n",
        "\n",
        "cnf_matrix = confusion_matrix(aggregated_data_test,actions)\n",
        "np.set_printoptions(precision=2)\n",
        "plt.figure()\n",
        "plt.figure()\n",
        "plot_confusion_matrix(cnf_matrix, classes=env.attack_types, normalize=True,\n",
        "                      title='Normalized confusion matrix')\n",
        "plt.savefig('results/confusion_matrix_adversarial.svg', format='svg', dpi=1000)\n"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Performance measures on Test data\n",
            "Accuracy =  0.8172\n",
            "F1 =  0.8076\n",
            "Precision_score =  0.8073\n",
            "recall_score =  0.8172\n",
            "Normalized confusion matrix\n",
            "[[9.34e-01 2.22e-02 3.34e-02 7.41e-03 3.29e-03]\n",
            " [3.43e-02 8.61e-01 1.25e-02 8.90e-02 2.82e-03]\n",
            " [2.48e-02 1.10e-01 8.22e-01 4.25e-02 1.24e-03]\n",
            " [6.16e-01 7.26e-04 1.05e-02 3.28e-01 4.50e-02]\n",
            " [1.15e-01 0.00e+00 5.60e-01 1.30e-01 1.95e-01]]\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "<matplotlib.figure.Figure at 0x7f6e03fa1ba8>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<matplotlib.figure.Figure at 0x7f6dea3efc88>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "metadata": {
        "id": "60L3BNptopsZ",
        "colab_type": "code",
        "outputId": "c9e531ee-a576-4d30-807f-4eddd1959f4e",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 151
        }
      },
      "cell_type": "code",
      "source": [
        "mapa = {0:'normal', 1:'DoS', 2:'Probe',3:'R2L',4:'U2R'}\n",
        "yt_app = pd.Series(maped).map(mapa)\n",
        "\n",
        "perf_per_class = pd.DataFrame(index=range(len(yt_app.unique())),columns=['name', 'acc','f1', 'pre','rec'])\n",
        "for i,x in enumerate(pd.Series(yt_app).value_counts().index):\n",
        "    y_test_hat_check = pd.Series(actions).map(mapa).copy()\n",
        "    y_test_hat_check[y_test_hat_check != x] = 'OTHER'\n",
        "    yt_app = pd.Series(maped).map(mapa).copy()\n",
        "    yt_app[yt_app != x] = 'OTHER'\n",
        "    ac=accuracy_score( yt_app,y_test_hat_check)\n",
        "    f1=f1_score( yt_app,y_test_hat_check,pos_label=x, average='binary')\n",
        "    pr=precision_score( yt_app,y_test_hat_check,pos_label=x, average='binary')\n",
        "    re=recall_score( yt_app,y_test_hat_check,pos_label=x, average='binary')\n",
        "    perf_per_class.iloc[i]=[x,ac,f1,pr,re]\n",
        "    \n",
        "print(\"\\r\\nOne vs All metrics: \\r\\n{}\".format(perf_per_class))\n"
      ],
      "execution_count": 0,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "\r\n",
            "One vs All metrics: \r\n",
            "     name       acc        f1       pre       rec\n",
            "0  normal  0.881166  0.871295  0.816716   0.93369\n",
            "1     DoS  0.932665  0.894334  0.929936  0.861357\n",
            "2     R2L  0.879524  0.399115   0.51047  0.327643\n",
            "3   Probe  0.956086  0.800725  0.780919  0.821561\n",
            "4     U2R  0.984874  0.186158  0.178082     0.195\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "metadata": {
        "id": "-i1UuwC8Zz_b",
        "colab_type": "code",
        "colab": {}
      },
      "cell_type": "code",
      "source": [
        ""
      ],
      "execution_count": 0,
      "outputs": []
    }
  ]
}